Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert entitled values #2705

Closed
Closed
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
6 changes: 3 additions & 3 deletions runtime/convertValues.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func exportValueWithInterpreter(
return cadence.NewMeteredAddress(inter, v), nil
case interpreter.PathValue:
return exportPathValue(inter, v)
case interpreter.TypeValue:
case *interpreter.TypeValue:
return exportTypeValue(v, inter), nil
case *interpreter.IDCapabilityValue:
return exportIDCapabilityValue(v, inter)
Expand Down Expand Up @@ -615,7 +615,7 @@ func exportPathValue(gauge common.MemoryGauge, v interpreter.PathValue) (cadence
)
}

func exportTypeValue(v interpreter.TypeValue, inter *interpreter.Interpreter) cadence.TypeValue {
func exportTypeValue(v *interpreter.TypeValue, inter *interpreter.Interpreter) cadence.TypeValue {
var typ sema.Type
if v.Type != nil {
typ = inter.MustConvertStaticToSemaType(v.Type)
Expand Down Expand Up @@ -1079,7 +1079,7 @@ func (i valueImporter) importPathValue(v cadence.Path) interpreter.PathValue {
)
}

func (i valueImporter) importTypeValue(v cadence.Type) (interpreter.TypeValue, error) {
func (i valueImporter) importTypeValue(v cadence.Type) (*interpreter.TypeValue, error) {
inter := i.inter

typ := ImportType(inter, v)
Expand Down
6 changes: 3 additions & 3 deletions runtime/convertValues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ func TestImportValue(t *testing.T) {
{
label: "Type<Int>()",
value: cadence.NewTypeValue(cadence.IntType{}),
expected: interpreter.TypeValue{Type: interpreter.PrimitiveStaticTypeInt},
expected: &interpreter.TypeValue{Type: interpreter.PrimitiveStaticTypeInt},
},
} {
test(tt)
Expand Down Expand Up @@ -2041,7 +2041,7 @@ func TestExportTypeValue(t *testing.T) {

t.Parallel()

value := interpreter.TypeValue{
value := &interpreter.TypeValue{
Type: nil,
}
actual, err := exportValueWithInterpreter(
Expand Down Expand Up @@ -2088,7 +2088,7 @@ func TestExportTypeValue(t *testing.T) {
inter := newTestInterpreter(t)
inter.Program = interpreter.ProgramFromChecker(checker)

ty := interpreter.TypeValue{
ty := &interpreter.TypeValue{
Type: &interpreter.IntersectionStaticType{
Types: []interpreter.InterfaceStaticType{
{
Expand Down
2 changes: 1 addition & 1 deletion runtime/interpreter/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,7 @@ func (d StorableDecoder) decodePublishedValue() (*PublishedValue, error) {
return NewPublishedValue(d.memoryGauge, addressValue, capabilityValue), nil
}

func (d StorableDecoder) decodeType() (TypeValue, error) {
func (d StorableDecoder) decodeType() (*TypeValue, error) {
const expectedLength = encodedTypeValueTypeLength

arraySize, err := d.decoder.DecodeArrayHead()
Expand Down
8 changes: 4 additions & 4 deletions runtime/interpreter/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3372,7 +3372,7 @@ func TestEncodeDecodeTypeValue(t *testing.T) {

t.Parallel()

value := TypeValue{
value := &TypeValue{
Type: ConvertSemaToPrimitiveStaticType(nil, sema.BoolType),
}

Expand All @@ -3399,7 +3399,7 @@ func TestEncodeDecodeTypeValue(t *testing.T) {

t.Parallel()

value := TypeValue{
value := &TypeValue{
Type: ConvertSemaToPrimitiveStaticType(nil, sema.IntType),
}

Expand All @@ -3426,7 +3426,7 @@ func TestEncodeDecodeTypeValue(t *testing.T) {

t.Parallel()

value := TypeValue{
value := &TypeValue{
Type: nil,
}

Expand Down Expand Up @@ -3457,7 +3457,7 @@ func TestEncodeDecodeTypeValue(t *testing.T) {
maxInlineElementSize := atree.MaxInlineArrayElementSize
identifier := strings.Repeat("x", int(maxInlineElementSize+1))

expected := TypeValue{
expected := &TypeValue{
Type: NewCompositeStaticTypeComputeTypeID(
nil,
common.AddressLocation{},
Expand Down
79 changes: 69 additions & 10 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3437,12 +3437,12 @@ func init() {
}

func dictionaryTypeFunction(invocation Invocation) Value {
keyTypeValue, ok := invocation.Arguments[0].(TypeValue)
keyTypeValue, ok := invocation.Arguments[0].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}

valueTypeValue, ok := invocation.Arguments[1].(TypeValue)
valueTypeValue, ok := invocation.Arguments[1].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand Down Expand Up @@ -3475,7 +3475,7 @@ func referenceTypeFunction(invocation Invocation) Value {
panic(errors.NewUnreachableError())
}

typeValue, ok := invocation.Arguments[1].(TypeValue)
typeValue, ok := invocation.Arguments[1].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand Down Expand Up @@ -3572,7 +3572,7 @@ func functionTypeFunction(invocation Invocation) Value {
panic(errors.NewUnreachableError())
}

typeValue, ok := invocation.Arguments[1].(TypeValue)
typeValue, ok := invocation.Arguments[1].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand All @@ -3584,7 +3584,7 @@ func functionTypeFunction(invocation Invocation) Value {
if parameterCount > 0 {
parameterTypes = make([]sema.Parameter, 0, parameterCount)
parameters.Iterate(interpreter, func(param Value) bool {
semaType := interpreter.MustConvertStaticToSemaType(param.(TypeValue).Type)
semaType := interpreter.MustConvertStaticToSemaType(param.(*TypeValue).Type)
parameterTypes = append(
parameterTypes,
sema.Parameter{
Expand Down Expand Up @@ -3763,7 +3763,7 @@ var runtimeTypeConstructors = []runtimeTypeConstructor{
converter: NewUnmeteredHostFunctionValue(
sema.OptionalTypeFunctionType,
func(invocation Invocation) Value {
typeValue, ok := invocation.Arguments[0].(TypeValue)
typeValue, ok := invocation.Arguments[0].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand All @@ -3783,7 +3783,7 @@ var runtimeTypeConstructors = []runtimeTypeConstructor{
converter: NewUnmeteredHostFunctionValue(
sema.VariableSizedArrayTypeFunctionType,
func(invocation Invocation) Value {
typeValue, ok := invocation.Arguments[0].(TypeValue)
typeValue, ok := invocation.Arguments[0].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand All @@ -3804,7 +3804,7 @@ var runtimeTypeConstructors = []runtimeTypeConstructor{
converter: NewUnmeteredHostFunctionValue(
sema.ConstantSizedArrayTypeFunctionType,
func(invocation Invocation) Value {
typeValue, ok := invocation.Arguments[0].(TypeValue)
typeValue, ok := invocation.Arguments[0].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand All @@ -3830,7 +3830,7 @@ var runtimeTypeConstructors = []runtimeTypeConstructor{
converter: NewUnmeteredHostFunctionValue(
sema.CapabilityTypeFunctionType,
func(invocation Invocation) Value {
typeValue, ok := invocation.Arguments[0].(TypeValue)
typeValue, ok := invocation.Arguments[0].(*TypeValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand Down Expand Up @@ -4524,6 +4524,65 @@ func (interpreter *Interpreter) MustConvertStaticAuthorizationToSemaAccess(auth
return access
}

// Converts the input value into a version compatible with the new entitlements feature,
// with the same members/operations accessible on any references as would have been accessible in the past.
// Modifies the input `v` in place
func (interpreter *Interpreter) ConvertValueToEntitlements(v Value) {
semaType := interpreter.MustSemaTypeOfValue(v)
entitledType := sema.ConvertToEntitledType(interpreter, semaType)

switch v := v.(type) {
case *EphemeralReferenceValue:
entitledReferenceType := entitledType.(*sema.ReferenceType)
staticAuthorization := ConvertSemaAccesstoStaticAuthorization(interpreter, entitledReferenceType.Authorization)
v.Authorization = staticAuthorization
v.BorrowedType = entitledReferenceType.Type
interpreter.ConvertValueToEntitlements(v.Value)
case *StorageReferenceValue:
entitledReferenceType := entitledType.(*sema.ReferenceType)
staticAuthorization := ConvertSemaAccesstoStaticAuthorization(interpreter, entitledReferenceType.Authorization)
v.Authorization = staticAuthorization
v.BorrowedType = entitledReferenceType.Type
// stored value is not converted; instead we will convert it upon load
case *SomeValue:
interpreter.ConvertValueToEntitlements(v.value)
// reset the storable, to be recomputed on next access
v.valueStorable = nil
case *CompositeValue:
// convert all the fields of this composite value to entitlements
v.Walk(interpreter, interpreter.ConvertValueToEntitlements)
case *ArrayValue:
entitledArrayType := entitledType.(sema.ArrayType)
v.semaType = entitledArrayType
v.Type = ConvertSemaArrayTypeToStaticArrayType(interpreter, entitledArrayType)
// convert all the elements of this array value to entitlements
v.Walk(interpreter, interpreter.ConvertValueToEntitlements)
case *DictionaryValue:
entitledDictionaryType := entitledType.(*sema.DictionaryType)
v.semaType = entitledDictionaryType
v.Type = ConvertSemaDictionaryTypeToStaticDictionaryType(interpreter, entitledDictionaryType)
// convert all the elements of this array value to entitlements
v.Walk(interpreter, interpreter.ConvertValueToEntitlements)
// capabilities should just have their borrow type updated;
// we will update their underlying value when the capability is borrowed
case *IDCapabilityValue:
entitledCapabilityValue := entitledType.(*sema.CapabilityType)
v.BorrowType = ConvertSemaToStaticType(interpreter, entitledCapabilityValue.BorrowType)
case *TypeValue:
if v.Type == nil {
return
}
// convert the static type of the value
v.Type = ConvertSemaToStaticType(
interpreter,
sema.ConvertToEntitledType(
interpreter,
interpreter.MustConvertStaticToSemaType(v.Type),
),
)
}
}

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

// Ensure the program for this location is loaded,
Expand Down Expand Up @@ -4767,7 +4826,7 @@ func (interpreter *Interpreter) isInstanceFunction(self Value) *HostFunctionValu
interpreter := invocation.Interpreter

firstArgument := invocation.Arguments[0]
typeValue, ok := firstArgument.(TypeValue)
typeValue, ok := firstArgument.(*TypeValue)

if !ok {
panic(errors.NewUnreachableError())
Expand Down
Loading