Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion bbq/vm/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ type Context struct {
// This cache-alike is maintained per execution.
// TODO: Re-use the conversions from the compiler.
// TODO: Maybe extend/share this between executions.
semaTypeCache map[sema.TypeID]sema.Type
semaTypeCache map[sema.TypeID]sema.Type
semaAccessCache map[interpreter.Authorization]sema.Access

// linkedGlobalsCache is a local cache-alike that is being used to hold already linked imports.
linkedGlobalsCache map[common.Location]LinkedGlobals
Expand Down Expand Up @@ -531,3 +532,22 @@ func (c *Context) GetEntitlementMapType(
func (c *Context) LocationRange() interpreter.LocationRange {
return c.getLocationRange()
}

func (c *Context) SemaAccessFromStaticAuthorization(auth interpreter.Authorization) (sema.Access, error) {
semaAccess, ok := c.semaAccessCache[auth]
if ok {
return semaAccess, nil
}

semaAccess, err := interpreter.ConvertStaticAuthorizationToSemaAccess(auth, c)
if err != nil {
return nil, err
}

if c.semaAccessCache == nil {
c.semaAccessCache = make(map[interpreter.Authorization]sema.Access)
}
c.semaAccessCache[auth] = semaAccess

return semaAccess, nil
}
38 changes: 21 additions & 17 deletions interpreter/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,93 +417,97 @@ type NoOpReferenceCreationContext struct{}

var _ interpreter.ReferenceCreationContext = NoOpReferenceCreationContext{}

func (n NoOpReferenceCreationContext) ClearReferencedResourceKindedValues(_ atree.ValueID) {
func (NoOpReferenceCreationContext) ClearReferencedResourceKindedValues(_ atree.ValueID) {
// NO-OP
}

func (n NoOpReferenceCreationContext) ReferencedResourceKindedValues(_ atree.ValueID) map[*interpreter.EphemeralReferenceValue]struct{} {
func (NoOpReferenceCreationContext) ReferencedResourceKindedValues(_ atree.ValueID) map[*interpreter.EphemeralReferenceValue]struct{} {
// NO-OP
return nil
}

func (n NoOpReferenceCreationContext) MaybeTrackReferencedResourceKindedValue(_ *interpreter.EphemeralReferenceValue) {
func (NoOpReferenceCreationContext) MaybeTrackReferencedResourceKindedValue(_ *interpreter.EphemeralReferenceValue) {
// NO-OP
}

func (n NoOpReferenceCreationContext) MeterMemory(_ common.MemoryUsage) error {
func (NoOpReferenceCreationContext) MeterMemory(_ common.MemoryUsage) error {
// NO-OP
return nil
}

func (n NoOpReferenceCreationContext) MeterComputation(_ common.ComputationUsage) error {
func (NoOpReferenceCreationContext) MeterComputation(_ common.ComputationUsage) error {
// NO-OP
return nil
}

func (n NoOpReferenceCreationContext) ReadStored(_ common.Address, _ common.StorageDomain, _ interpreter.StorageMapKey) interpreter.Value {
func (NoOpReferenceCreationContext) ReadStored(_ common.Address, _ common.StorageDomain, _ interpreter.StorageMapKey) interpreter.Value {
// NO-OP
return nil
}

func (n NoOpReferenceCreationContext) GetEntitlementType(_ interpreter.TypeID) (*sema.EntitlementType, error) {
func (NoOpReferenceCreationContext) GetEntitlementType(_ interpreter.TypeID) (*sema.EntitlementType, error) {
// NO-OP
return nil, nil
}

func (n NoOpReferenceCreationContext) GetEntitlementMapType(_ interpreter.TypeID) (*sema.EntitlementMapType, error) {
func (NoOpReferenceCreationContext) GetEntitlementMapType(_ interpreter.TypeID) (*sema.EntitlementMapType, error) {
// NO-OP
return nil, nil
}

func (n NoOpReferenceCreationContext) GetInterfaceType(_ common.Location, _ string, _ interpreter.TypeID) (*sema.InterfaceType, error) {
func (NoOpReferenceCreationContext) GetInterfaceType(_ common.Location, _ string, _ interpreter.TypeID) (*sema.InterfaceType, error) {
// NO-OP
return nil, nil
}

func (n NoOpReferenceCreationContext) GetCompositeType(_ common.Location, _ string, _ interpreter.TypeID) (*sema.CompositeType, error) {
func (NoOpReferenceCreationContext) GetCompositeType(_ common.Location, _ string, _ interpreter.TypeID) (*sema.CompositeType, error) {
// NO-OP
return nil, nil
}

func (n NoOpReferenceCreationContext) IsTypeInfoRecovered(_ common.Location) bool {
func (NoOpReferenceCreationContext) IsTypeInfoRecovered(_ common.Location) bool {
// NO-OP
return false
}

func (n NoOpReferenceCreationContext) SemaTypeFromStaticType(_ interpreter.StaticType) sema.Type {
func (NoOpReferenceCreationContext) SemaTypeFromStaticType(_ interpreter.StaticType) sema.Type {
// NO-OP
return nil
}

func (NoOpReferenceCreationContext) SemaAccessFromStaticAuthorization(interpreter.Authorization) (sema.Access, error) {
panic(errors.NewUnreachableError())
}

type NoOpFunctionCreationContext struct {
//Just to make the compiler happy
interpreter.ResourceDestructionContext
}

var _ interpreter.FunctionCreationContext = NoOpFunctionCreationContext{}

func (n NoOpFunctionCreationContext) ClearReferencedResourceKindedValues(_ atree.ValueID) {
func (NoOpFunctionCreationContext) ClearReferencedResourceKindedValues(_ atree.ValueID) {
// NO-OP
}

func (n NoOpFunctionCreationContext) ReferencedResourceKindedValues(
func (NoOpFunctionCreationContext) ReferencedResourceKindedValues(
_ atree.ValueID,
) map[*interpreter.EphemeralReferenceValue]struct{} {
// NO-OP
return nil
}

func (n NoOpFunctionCreationContext) CheckInvalidatedResourceOrResourceReference(
func (NoOpFunctionCreationContext) CheckInvalidatedResourceOrResourceReference(
_ interpreter.Value,
) {
// NO-OP
}

func (n NoOpFunctionCreationContext) MaybeTrackReferencedResourceKindedValue(_ *interpreter.EphemeralReferenceValue) {
func (NoOpFunctionCreationContext) MaybeTrackReferencedResourceKindedValue(_ *interpreter.EphemeralReferenceValue) {
// NO-OP
}

func (n NoOpFunctionCreationContext) MeterMemory(_ common.MemoryUsage) error {
func (NoOpFunctionCreationContext) MeterMemory(_ common.MemoryUsage) error {
// NO-OP
return nil
}
Expand Down
53 changes: 29 additions & 24 deletions interpreter/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type TypeConverter interface {
common.MemoryGauge
StaticTypeConversionHandler
SemaTypeFromStaticType(staticType StaticType) sema.Type
SemaAccessFromStaticAuthorization(auth Authorization) (sema.Access, error)
}

var _ TypeConverter = &Interpreter{}
Expand Down Expand Up @@ -538,98 +539,102 @@ type NoOpStringContext struct {

var _ ValueStringContext = NoOpStringContext{}

func (ctx NoOpStringContext) MeterMemory(_ common.MemoryUsage) error {
func (NoOpStringContext) MeterMemory(_ common.MemoryUsage) error {
return nil
}

func (ctx NoOpStringContext) MeterComputation(_ common.ComputationUsage) error {
func (NoOpStringContext) MeterComputation(_ common.ComputationUsage) error {
return nil
}

func (ctx NoOpStringContext) WithContainerMutationPrevention(_ atree.ValueID, f func()) {
func (NoOpStringContext) WithContainerMutationPrevention(_ atree.ValueID, f func()) {
f()
}

func (ctx NoOpStringContext) ValidateContainerMutation(_ atree.ValueID) {
func (NoOpStringContext) ValidateContainerMutation(_ atree.ValueID) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) EnforceNotResourceDestruction(_ atree.ValueID) {
func (NoOpStringContext) EnforceNotResourceDestruction(_ atree.ValueID) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) ReadStored(_ common.Address, _ common.StorageDomain, _ StorageMapKey) Value {
func (NoOpStringContext) ReadStored(_ common.Address, _ common.StorageDomain, _ StorageMapKey) Value {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) WriteStored(_ common.Address, _ common.StorageDomain, _ StorageMapKey, _ Value) (existed bool) {
func (NoOpStringContext) WriteStored(_ common.Address, _ common.StorageDomain, _ StorageMapKey, _ Value) (existed bool) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) Storage() Storage {
func (NoOpStringContext) Storage() Storage {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) MaybeValidateAtreeValue(_ atree.Value) {
func (NoOpStringContext) MaybeValidateAtreeValue(_ atree.Value) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) MaybeValidateAtreeStorage() {
func (NoOpStringContext) MaybeValidateAtreeStorage() {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) MaybeTrackReferencedResourceKindedValue(_ *EphemeralReferenceValue) {
func (NoOpStringContext) MaybeTrackReferencedResourceKindedValue(_ *EphemeralReferenceValue) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) ClearReferencedResourceKindedValues(_ atree.ValueID) {
func (NoOpStringContext) ClearReferencedResourceKindedValues(_ atree.ValueID) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) ReferencedResourceKindedValues(_ atree.ValueID) map[*EphemeralReferenceValue]struct{} {
func (NoOpStringContext) ReferencedResourceKindedValues(_ atree.ValueID) map[*EphemeralReferenceValue]struct{} {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) OnResourceOwnerChange(_ *CompositeValue, _ common.Address, _ common.Address) {
func (NoOpStringContext) OnResourceOwnerChange(_ *CompositeValue, _ common.Address, _ common.Address) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) RecordStorageMutation() {
func (NoOpStringContext) RecordStorageMutation() {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) StorageMutatedDuringIteration() bool {
func (NoOpStringContext) StorageMutatedDuringIteration() bool {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) InStorageIteration() bool {
func (NoOpStringContext) InStorageIteration() bool {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) SetInStorageIteration(_ bool) {
func (NoOpStringContext) SetInStorageIteration(_ bool) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) GetEntitlementType(_ TypeID) (*sema.EntitlementType, error) {
func (NoOpStringContext) GetEntitlementType(_ TypeID) (*sema.EntitlementType, error) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) GetEntitlementMapType(_ TypeID) (*sema.EntitlementMapType, error) {
func (NoOpStringContext) GetEntitlementMapType(_ TypeID) (*sema.EntitlementMapType, error) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) GetInterfaceType(_ common.Location, _ string, _ TypeID) (*sema.InterfaceType, error) {
func (NoOpStringContext) GetInterfaceType(_ common.Location, _ string, _ TypeID) (*sema.InterfaceType, error) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) GetCompositeType(_ common.Location, _ string, _ TypeID) (*sema.CompositeType, error) {
func (NoOpStringContext) GetCompositeType(_ common.Location, _ string, _ TypeID) (*sema.CompositeType, error) {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) IsTypeInfoRecovered(_ common.Location) bool {
func (NoOpStringContext) IsTypeInfoRecovered(_ common.Location) bool {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) SemaTypeFromStaticType(_ StaticType) sema.Type {
func (NoOpStringContext) SemaTypeFromStaticType(_ StaticType) sema.Type {
panic(errors.NewUnreachableError())
}

func (NoOpStringContext) SemaAccessFromStaticAuthorization(Authorization) (sema.Access, error) {
panic(errors.NewUnreachableError())
}
15 changes: 4 additions & 11 deletions interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5187,17 +5187,6 @@ func (interpreter *Interpreter) GetEntitlementMapType(typeID common.TypeID) (*se
return ty, nil
}

func MustConvertStaticAuthorizationToSemaAccess(
handler StaticAuthorizationConversionHandler,
auth Authorization,
) sema.Access {
access, err := ConvertStaticAuthorizationToSemaAccess(auth, handler)
if err != nil {
panic(err)
}
return access
}

func (interpreter *Interpreter) getElaboration(location common.Location) *sema.Elaboration {

// Ensure the program for this location is loaded,
Expand Down Expand Up @@ -6400,6 +6389,10 @@ func (interpreter *Interpreter) MaybeUpdateStorageReferenceMemberReceiver(
return member
}

func (interpreter *Interpreter) SemaAccessFromStaticAuthorization(auth Authorization) (sema.Access, error) {
return ConvertStaticAuthorizationToSemaAccess(auth, interpreter)
}

func StorageReference(
context ValueStaticTypeContext,
storageReference *StorageReferenceValue,
Expand Down
8 changes: 7 additions & 1 deletion interpreter/statictype.go
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,12 @@ func ConvertSemaTransactionToStaticTransactionType(
)
}

// ConvertStaticAuthorizationToSemaAccess converts authorization of static-types
// to the sema-type representation of the same.
//
// **IMPORTANT**: Do not use this function directly. Instead, use the
// `SemaAccessFromStaticAuthorization` method of the `TypeConverter` interface,
// since it will cache and re-use the conversion results.
func ConvertStaticAuthorizationToSemaAccess(
auth Authorization,
handler StaticAuthorizationConversionHandler,
Expand Down Expand Up @@ -1370,7 +1376,7 @@ func ConvertStaticToSemaType(
return nil, err
}

access, err := ConvertStaticAuthorizationToSemaAccess(t.Authorization, context)
access, err := context.SemaAccessFromStaticAuthorization(t.Authorization)

if err != nil {
return nil, err
Expand Down
4 changes: 4 additions & 0 deletions interpreter/statictype_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,10 @@ func (s staticTypeConversionHandler) SemaTypeFromStaticType(staticType StaticTyp
return MustConvertStaticToSemaType(staticType, s)
}

func (s staticTypeConversionHandler) SemaAccessFromStaticAuthorization(auth Authorization) (sema.Access, error) {
return ConvertStaticAuthorizationToSemaAccess(auth, s)
}

func TestIntersectionStaticType_ID(t *testing.T) {
t.Parallel()

Expand Down
8 changes: 7 additions & 1 deletion interpreter/value_ephemeral_reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,16 @@ func (v *EphemeralReferenceValue) GetTypeKey(context MemberAccessibleContext, ke
self := v.Value

if selfComposite, isComposite := self.(*CompositeValue); isComposite {

semaAccess, err := context.SemaAccessFromStaticAuthorization(v.Authorization)
if err != nil {
panic(err)
}

return selfComposite.getTypeKey(
context,
key,
MustConvertStaticAuthorizationToSemaAccess(context, v.Authorization),
semaAccess,
)
}

Expand Down
5 changes: 4 additions & 1 deletion interpreter/value_storage_reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,10 @@ func (v *StorageReferenceValue) GetTypeKey(
self := v.mustReferencedValue(context)

if selfComposite, isComposite := self.(*CompositeValue); isComposite {
access := MustConvertStaticAuthorizationToSemaAccess(context, v.Authorization)
access, err := context.SemaAccessFromStaticAuthorization(v.Authorization)
if err != nil {
panic(err)
}
return selfComposite.getTypeKey(
context,
key,
Expand Down
Loading