Skip to content
Merged
19 changes: 18 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
Comment thread
SupunS marked this conversation as resolved.

// 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,19 @@ func (c *Context) GetEntitlementMapType(
func (c *Context) LocationRange() interpreter.LocationRange {
return c.getLocationRange()
}

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

semaAccess = interpreter.MustConvertStaticAuthorizationToSemaAccess(c, auth)

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

return semaAccess
}
4 changes: 4 additions & 0 deletions interpreter/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,10 @@ func (n NoOpReferenceCreationContext) SemaTypeFromStaticType(_ interpreter.Stati
return nil
}

func (n NoOpReferenceCreationContext) SemaAccessFromStaticAuthorization(auth interpreter.Authorization) sema.Access {
panic(errors.NewUnreachableError())
}

type NoOpFunctionCreationContext struct {
//Just to make the compiler happy
interpreter.ResourceDestructionContext
Expand Down
5 changes: 5 additions & 0 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
}

var _ TypeConverter = &Interpreter{}
Expand Down Expand Up @@ -633,3 +634,7 @@ func (ctx NoOpStringContext) IsTypeInfoRecovered(_ common.Location) bool {
func (ctx NoOpStringContext) SemaTypeFromStaticType(_ StaticType) sema.Type {
panic(errors.NewUnreachableError())
}

func (ctx NoOpStringContext) SemaAccessFromStaticAuthorization(auth Authorization) sema.Access {
Comment thread
SupunS marked this conversation as resolved.
Outdated
panic(errors.NewUnreachableError())
}
4 changes: 4 additions & 0 deletions interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6400,6 +6400,10 @@ func (interpreter *Interpreter) MaybeUpdateStorageReferenceMemberReceiver(
return member
}

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

func StorageReference(
context ValueStaticTypeContext,
storageReference *StorageReferenceValue,
Expand Down
5 changes: 5 additions & 0 deletions interpreter/primitivestatictype.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ type PrimitiveStaticType uint

var _ StaticType = PrimitiveStaticType(0)

// Some simple types are conforming types.
var _ ConformingStaticType = PrimitiveStaticType(0)

const primitiveStaticTypePrefix = "PrimitiveStaticType"

var primitiveStaticTypeConstantLength = len(primitiveStaticTypePrefix) + 2 // + 2 for parentheses
Expand Down Expand Up @@ -260,6 +263,8 @@ const (

func (PrimitiveStaticType) isStaticType() {}

func (PrimitiveStaticType) isConformingStaticType() {}

func (t PrimitiveStaticType) elementSize() uint {
switch t {
case
Expand Down
63 changes: 63 additions & 0 deletions interpreter/statictype.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type CompositeStaticType struct {
}

var _ StaticType = &CompositeStaticType{}
var _ ConformingStaticType = &CompositeStaticType{}

func NewCompositeStaticType(
memoryGauge common.MemoryGauge,
Expand Down Expand Up @@ -104,6 +105,8 @@ func NewCompositeStaticTypeComputeTypeID(

func (*CompositeStaticType) isStaticType() {}

func (*CompositeStaticType) isConformingStaticType() {}

func (*CompositeStaticType) elementSize() uint {
return UnknownElementSize
}
Expand Down Expand Up @@ -143,6 +146,7 @@ type InterfaceStaticType struct {
}

var _ StaticType = &InterfaceStaticType{}
var _ ConformingStaticType = &InterfaceStaticType{}

func NewInterfaceStaticType(
memoryGauge common.MemoryGauge,
Expand Down Expand Up @@ -184,6 +188,8 @@ func NewInterfaceStaticTypeComputeTypeID(

func (*InterfaceStaticType) isStaticType() {}

func (*InterfaceStaticType) isConformingStaticType() {}

func (*InterfaceStaticType) elementSize() uint {
return UnknownElementSize
}
Expand Down Expand Up @@ -299,6 +305,7 @@ type InclusiveRangeStaticType struct {
}

var _ StaticType = InclusiveRangeStaticType{}
var _ ParameterizedStaticType = InclusiveRangeStaticType{}

func NewInclusiveRangeStaticType(
memoryGauge common.MemoryGauge,
Expand Down Expand Up @@ -346,6 +353,19 @@ func (t InclusiveRangeStaticType) IsDeprecated() bool {
return t.ElementType.IsDeprecated()
}

func (t InclusiveRangeStaticType) BaseType() StaticType {
if t.ElementType == nil {
return nil
}
return &InclusiveRangeStaticType{}
}

func (t InclusiveRangeStaticType) TypeArguments() []StaticType {
return []StaticType{
t.ElementType,
}
}

// ConstantSizedStaticType

type ConstantSizedStaticType struct {
Expand Down Expand Up @@ -926,6 +946,7 @@ type CapabilityStaticType struct {
}

var _ StaticType = &CapabilityStaticType{}
var _ ParameterizedStaticType = &CapabilityStaticType{}

func NewCapabilityStaticType(
memoryGauge common.MemoryGauge,
Expand Down Expand Up @@ -991,6 +1012,30 @@ func (t *CapabilityStaticType) IsDeprecated() bool {
return t.BorrowType.IsDeprecated()
}

func (t *CapabilityStaticType) BaseType() StaticType {
// Note: Must be same as `sema.CapabilityType.BaseType()`
if t.BorrowType == nil {
Comment thread
SupunS marked this conversation as resolved.
return nil
}

return PrimitiveStaticTypeCapability
}

func (t *CapabilityStaticType) TypeArguments() []StaticType {
// Note: Must be same as `sema.CapabilityType.TypeArguments()`
borrowType := t.BorrowType
if borrowType == nil {
borrowType = &ReferenceStaticType{
ReferencedType: PrimitiveStaticTypeAny,
Authorization: UnauthorizedAccess,
}
}

return []StaticType{
borrowType,
}
}

// Conversion

func ConvertSemaToStaticType(memoryGauge common.MemoryGauge, t sema.Type) StaticType {
Expand Down Expand Up @@ -1063,6 +1108,11 @@ func ConvertSemaToStaticType(memoryGauge common.MemoryGauge, t sema.Type) Static

case *sema.TransactionType:
return ConvertSemaTransactionToStaticTransactionType(memoryGauge, t)

case *sema.GenericType:
// Function types could have generic-typed returns/parameters. e.g: builtin functions.
// Since they are not resolved, the type is unknown here.
return PrimitiveStaticTypeUnknown
Comment thread
SupunS marked this conversation as resolved.
}

return nil
Expand Down Expand Up @@ -1498,3 +1548,16 @@ func (p TypeParameter) String() string {
}
return builder.String()
}

type ParameterizedStaticType interface {
StaticType
BaseType() StaticType
TypeArguments() []StaticType
}

// ConformingStaticType is any static type that conforms to some interface.
// This is the static-type counterpart of `sema.ConformingType`.
type ConformingStaticType interface {
StaticType
isConformingStaticType()
}
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 {
return MustConvertStaticAuthorizationToSemaAccess(s, auth)
}

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

Expand Down
Loading
Loading