Skip to content

Commit

Permalink
Merge pull request #3698 from onflow/bastian/decouple-values-from-int…
Browse files Browse the repository at this point in the history
…erpreter

Decouple interpreter values from interpreter
  • Loading branch information
turbolent authored Feb 12, 2025
2 parents f9aabc2 + 1c46ead commit 95b96a0
Show file tree
Hide file tree
Showing 75 changed files with 1,556 additions and 1,603 deletions.
2 changes: 1 addition & 1 deletion cmd/decode-state-values/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ func loadStorageKey(

if composite, ok := v.(*interpreter.CompositeValue); ok &&
composite.Kind == common.CompositeKindResource &&
composite.ResourceUUID(inter, interpreter.EmptyLocationRange) == nil {
composite.ResourceUUID(inter) == nil {

log.Printf(
"Failed to get UUID for resource @ 0x%x %s",
Expand Down
14 changes: 7 additions & 7 deletions interpreter/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ func TestInterpretAccountStorageLoad(t *testing.T) {

require.IsType(t, &interpreter.SomeValue{}, value)

innerValue := value.(*interpreter.SomeValue).InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := value.(*interpreter.SomeValue).InnerValue()

assert.IsType(t, &interpreter.CompositeValue{}, innerValue)

Expand Down Expand Up @@ -790,7 +790,7 @@ func TestInterpretAccountStorageLoad(t *testing.T) {

require.IsType(t, &interpreter.SomeValue{}, value)

innerValue := value.(*interpreter.SomeValue).InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := value.(*interpreter.SomeValue).InnerValue()

assert.IsType(t, &interpreter.CompositeValue{}, innerValue)

Expand Down Expand Up @@ -872,7 +872,7 @@ func TestInterpretAccountStorageCopy(t *testing.T) {

require.IsType(t, &interpreter.SomeValue{}, value)

innerValue := value.(*interpreter.SomeValue).InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := value.(*interpreter.SomeValue).InnerValue()

assert.IsType(t, &interpreter.CompositeValue{}, innerValue)

Expand Down Expand Up @@ -1005,7 +1005,7 @@ func TestInterpretAccountStorageBorrow(t *testing.T) {

require.IsType(t, &interpreter.SomeValue{}, value)

innerValue := value.(*interpreter.SomeValue).InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := value.(*interpreter.SomeValue).InnerValue()

assert.IsType(t, &interpreter.StorageReferenceValue{}, innerValue)

Expand Down Expand Up @@ -1044,7 +1044,7 @@ func TestInterpretAccountStorageBorrow(t *testing.T) {

require.IsType(t, &interpreter.SomeValue{}, value)

innerValue = value.(*interpreter.SomeValue).InnerValue(inter, interpreter.EmptyLocationRange)
innerValue = value.(*interpreter.SomeValue).InnerValue()

assert.IsType(t, &interpreter.StorageReferenceValue{}, innerValue)

Expand Down Expand Up @@ -1183,7 +1183,7 @@ func TestInterpretAccountStorageBorrow(t *testing.T) {

require.IsType(t, &interpreter.SomeValue{}, value)

innerValue := value.(*interpreter.SomeValue).InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := value.(*interpreter.SomeValue).InnerValue()

assert.IsType(t, &interpreter.StorageReferenceValue{}, innerValue)

Expand Down Expand Up @@ -1222,7 +1222,7 @@ func TestInterpretAccountStorageBorrow(t *testing.T) {

require.IsType(t, &interpreter.SomeValue{}, value)

innerValue = value.(*interpreter.SomeValue).InnerValue(inter, interpreter.EmptyLocationRange)
innerValue = value.(*interpreter.SomeValue).InnerValue()

assert.IsType(t, &interpreter.StorageReferenceValue{}, innerValue)

Expand Down
4 changes: 2 additions & 2 deletions interpreter/attachments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1517,8 +1517,8 @@ func TestInterpretAttachmentDestructor(t *testing.T) {

require.Len(t, events, 2)
require.Equal(t, "A.ResourceDestroyed", events[0].QualifiedIdentifier)
require.Equal(t, interpreter.NewUnmeteredStringValue("foo"), events[0].GetField(inter, interpreter.EmptyLocationRange, "foo"))
require.Equal(t, interpreter.NewIntValueFromInt64(nil, 2), events[0].GetField(inter, interpreter.EmptyLocationRange, "bar"))
require.Equal(t, interpreter.NewUnmeteredStringValue("foo"), events[0].GetField(inter, "foo"))
require.Equal(t, interpreter.NewIntValueFromInt64(nil, 2), events[0].GetField(inter, "bar"))
require.Equal(t, "R.ResourceDestroyed", events[1].QualifiedIdentifier)
})
}
Expand Down
2 changes: 1 addition & 1 deletion interpreter/builtinfunctions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func TestInterpretAddressFromString(t *testing.T) {
addressOpt, ok := res.(*interpreter.SomeValue)
require.True(t, ok)

innerValue := addressOpt.InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := addressOpt.InnerValue()
addressVal, ok := innerValue.(interpreter.AddressValue)
require.True(t, ok)
require.Equal(t, expected, addressVal.ToAddress().HexWithPrefix())
Expand Down
23 changes: 8 additions & 15 deletions interpreter/dynamic_casting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -607,8 +607,7 @@ func TestInterpretDynamicCastingStruct(t *testing.T) {

require.IsType(t,
&interpreter.CompositeValue{},
inter.Globals.Get("y").GetValue(inter).(*interpreter.SomeValue).
InnerValue(inter, interpreter.EmptyLocationRange),
inter.Globals.Get("y").GetValue(inter).(*interpreter.SomeValue).InnerValue(),
)
})
}
Expand Down Expand Up @@ -757,8 +756,7 @@ func testResourceCastValid(t *testing.T, types, fromType string, targetType stri

require.IsType(t,
&interpreter.CompositeValue{},
value.(*interpreter.SomeValue).
InnerValue(inter, interpreter.EmptyLocationRange),
value.(*interpreter.SomeValue).InnerValue(),
)

case ast.OperationForceCast:
Expand Down Expand Up @@ -903,8 +901,7 @@ func testStructCastValid(t *testing.T, types, fromType string, targetType string

require.IsType(t,
&interpreter.CompositeValue{},
value.(*interpreter.SomeValue).
InnerValue(inter, interpreter.EmptyLocationRange),
value.(*interpreter.SomeValue).InnerValue(),
)

case ast.OperationForceCast:
Expand Down Expand Up @@ -1214,7 +1211,7 @@ func TestInterpretDynamicCastingArray(t *testing.T) {
require.IsType(t, zValue, &interpreter.SomeValue{})
zSome := zValue.(*interpreter.SomeValue)

innerValue := zSome.InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := zSome.InnerValue()
require.IsType(t, innerValue, &interpreter.ArrayValue{})
innerArray := innerValue.(*interpreter.ArrayValue)

Expand Down Expand Up @@ -2279,8 +2276,7 @@ func testReferenceCastValid(t *testing.T, types, fromType, targetType string, op

require.IsType(t,
&interpreter.EphemeralReferenceValue{},
value.(*interpreter.SomeValue).
InnerValue(inter, interpreter.EmptyLocationRange),
value.(*interpreter.SomeValue).InnerValue(),
)

case ast.OperationForceCast:
Expand Down Expand Up @@ -4108,8 +4104,7 @@ func TestInterpretDynamicCastingOptionalUnwrapping(t *testing.T) {

require.IsType(t,
&interpreter.CompositeValue{},
value.(*interpreter.SomeValue).
InnerValue(inter, interpreter.EmptyLocationRange),
value.(*interpreter.SomeValue).InnerValue(),
)
})

Expand Down Expand Up @@ -4164,8 +4159,7 @@ func TestInterpretDynamicCastingOptionalUnwrapping(t *testing.T) {

require.IsType(t,
&interpreter.CompositeValue{},
result.(*interpreter.SomeValue).
InnerValue(inter, interpreter.EmptyLocationRange),
result.(*interpreter.SomeValue).InnerValue(),
)

})
Expand Down Expand Up @@ -4201,8 +4195,7 @@ func TestInterpretDynamicCastingOptionalUnwrapping(t *testing.T) {

require.IsType(t,
&interpreter.CompositeValue{},
result.(*interpreter.SomeValue).
InnerValue(inter, interpreter.EmptyLocationRange),
result.(*interpreter.SomeValue).InnerValue(),
)

})
Expand Down
2 changes: 1 addition & 1 deletion interpreter/enum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func TestInterpretEnumInContract(t *testing.T) {
require.IsType(t, &interpreter.CompositeValue{}, c)
contract := c.(*interpreter.CompositeValue)

eValue := contract.GetField(inter, interpreter.EmptyLocationRange, "e")
eValue := contract.GetField(inter, "e")
require.NotNil(t, eValue)

require.IsType(t, &interpreter.CompositeValue{}, eValue)
Expand Down
10 changes: 5 additions & 5 deletions interpreter/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestInterpretResultVariable(t *testing.T) {
t,
inter,
interpreter.UInt8Value(1),
resource.GetField(inter, interpreter.EmptyLocationRange, "id"),
resource.GetField(inter, "id"),
)
})

Expand Down Expand Up @@ -93,7 +93,7 @@ func TestInterpretResultVariable(t *testing.T) {
require.IsType(t, &interpreter.SomeValue{}, result)
someValue := result.(*interpreter.SomeValue)

innerValue := someValue.InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := someValue.InnerValue()
require.IsType(t, &interpreter.CompositeValue{}, innerValue)

resource := innerValue.(*interpreter.CompositeValue)
Expand All @@ -102,7 +102,7 @@ func TestInterpretResultVariable(t *testing.T) {
t,
inter,
interpreter.UInt8Value(1),
resource.GetField(inter, interpreter.EmptyLocationRange, "id"),
resource.GetField(inter, "id"),
)
})

Expand Down Expand Up @@ -157,7 +157,7 @@ func TestInterpretResultVariable(t *testing.T) {
require.IsType(t, &interpreter.SomeValue{}, result)
someValue := result.(*interpreter.SomeValue)

innerValue := someValue.InnerValue(inter, interpreter.EmptyLocationRange)
innerValue := someValue.InnerValue()
require.IsType(t, &interpreter.CompositeValue{}, innerValue)

resource := innerValue.(*interpreter.CompositeValue)
Expand All @@ -166,7 +166,7 @@ func TestInterpretResultVariable(t *testing.T) {
t,
inter,
interpreter.UInt8Value(1),
resource.GetField(inter, interpreter.EmptyLocationRange, "id"),
resource.GetField(inter, "id"),
)
})

Expand Down
10 changes: 6 additions & 4 deletions interpreter/hashablevalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@ package interpreter

import (
"github.com/onflow/atree"

"github.com/onflow/cadence/common"
)

// HashableValue is an immutable value that can be hashed
type HashableValue interface {
Value
HashInput(interpreter *Interpreter, locationRange LocationRange, scratch []byte) []byte
HashInput(memoryGauge common.MemoryGauge, locationRange LocationRange, scratch []byte) []byte
}

func newHashInputProvider(interpreter *Interpreter, locationRange LocationRange) atree.HashInputProvider {
func newHashInputProvider(memoryGauge common.MemoryGauge, locationRange LocationRange) atree.HashInputProvider {
return func(value atree.Value, scratch []byte) ([]byte, error) {
hashInput := MustConvertStoredValue(interpreter, value).(HashableValue).
HashInput(interpreter, locationRange, scratch)
hashInput := MustConvertStoredValue(memoryGauge, value).(HashableValue).
HashInput(memoryGauge, locationRange, scratch)
return hashInput, nil
}
}
Expand Down
24 changes: 15 additions & 9 deletions interpreter/inclusive_range_iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package interpreter

import (
"github.com/onflow/cadence/common"
"github.com/onflow/cadence/errors"
"github.com/onflow/cadence/sema"
)
Expand All @@ -35,19 +36,24 @@ type InclusiveRangeIterator struct {

var _ ValueIterator = &InclusiveRangeIterator{}

type InclusiveRangeIteratorContext interface {
common.MemoryGauge
NumberValueArithmeticContext
}

func NewInclusiveRangeIterator(
interpreter *Interpreter,
context InclusiveRangeIteratorContext,
locationRange LocationRange,
v *CompositeValue,
typ InclusiveRangeStaticType,
) *InclusiveRangeIterator {
startValue := getFieldAsIntegerValue(interpreter, v, locationRange, sema.InclusiveRangeTypeStartFieldName)
startValue := getFieldAsIntegerValue(context, v, sema.InclusiveRangeTypeStartFieldName)

zeroValue := GetSmallIntegerValue(0, typ.ElementType)
endValue := getFieldAsIntegerValue(interpreter, v, locationRange, sema.InclusiveRangeTypeEndFieldName)
endValue := getFieldAsIntegerValue(context, v, sema.InclusiveRangeTypeEndFieldName)

stepValue := getFieldAsIntegerValue(interpreter, v, locationRange, sema.InclusiveRangeTypeStepFieldName)
stepNegative := stepValue.Less(interpreter, zeroValue, locationRange)
stepValue := getFieldAsIntegerValue(context, v, sema.InclusiveRangeTypeStepFieldName)
stepNegative := stepValue.Less(context, zeroValue, locationRange)

return &InclusiveRangeIterator{
rangeValue: v,
Expand All @@ -58,18 +64,18 @@ func NewInclusiveRangeIterator(
}
}

func (i *InclusiveRangeIterator) Next(interpreter *Interpreter, locationRange LocationRange) Value {
func (i *InclusiveRangeIterator) Next(context ValueIteratorContext, locationRange LocationRange) Value {
valueToReturn := i.next

// Ensure that valueToReturn is within the bounds.
if i.stepNegative && bool(valueToReturn.Less(interpreter, i.end, locationRange)) {
if i.stepNegative && bool(valueToReturn.Less(context, i.end, locationRange)) {
return nil
} else if !i.stepNegative && bool(valueToReturn.Greater(interpreter, i.end, locationRange)) {
} else if !i.stepNegative && bool(valueToReturn.Greater(context, i.end, locationRange)) {
return nil
}

// Update the next value.
nextValueToReturn, ok := valueToReturn.Plus(interpreter, i.step, locationRange).(IntegerValue)
nextValueToReturn, ok := valueToReturn.Plus(context, i.step, locationRange).(IntegerValue)
if !ok {
panic(errors.NewUnreachableError())
}
Expand Down
4 changes: 2 additions & 2 deletions interpreter/inspect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ func TestInspectValue(t *testing.T) {
// Get actually stored values.
// The values above were removed when they were inserted into the containers.

optionalValue := compositeValue.GetField(inter, EmptyLocationRange, "value").(*SomeValue)
arrayValue := optionalValue.InnerValue(inter, EmptyLocationRange).(*ArrayValue)
optionalValue := compositeValue.GetField(inter, "value").(*SomeValue)
arrayValue := optionalValue.InnerValue().(*ArrayValue)
dictValue := arrayValue.Get(inter, EmptyLocationRange, 0).(*DictionaryValue)
dictValueKey := NewUnmeteredStringValue("hello world")

Expand Down
55 changes: 55 additions & 0 deletions interpreter/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Cadence - The resource-oriented smart contract programming language
*
* Copyright Flow Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package interpreter

import (
"github.com/onflow/cadence/common"
"github.com/onflow/cadence/sema"
)

type TypeConverter interface {
MustConvertStaticToSemaType(staticType StaticType) sema.Type
}

var _ TypeConverter = &Interpreter{}

type SubTypeChecker interface {
IsSubTypeOfSemaType(staticSubType StaticType, superType sema.Type) bool
}

var _ SubTypeChecker = &Interpreter{}

type StorageReader interface {
ReadStored(
storageAddress common.Address,
domain common.StorageDomain,
identifier StorageMapKey,
) Value
}

var _ StorageReader = &Interpreter{}

type ValueStaticTypeContext interface {
common.MemoryGauge
StorageReader
TypeConverter
SubTypeChecker
}

var _ ValueStaticTypeContext = &Interpreter{}
Loading

0 comments on commit 95b96a0

Please sign in to comment.