Skip to content

Commit

Permalink
Merge pull request #3600 from onflow/supun/port-fixes
Browse files Browse the repository at this point in the history
Port bug fixes from internal repo
  • Loading branch information
SupunS authored Oct 8, 2024
2 parents b55d056 + d9709a5 commit 528b9ae
Show file tree
Hide file tree
Showing 21 changed files with 510 additions and 174 deletions.
35 changes: 23 additions & 12 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,11 @@ func (interpreter *Interpreter) InvokeExternally(
var base *EphemeralReferenceValue
var boundAuth Authorization
if boundFunc, ok := functionValue.(BoundFunctionValue); ok {
self = boundFunc.Self
self = boundFunc.SelfReference.ReferencedValue(
interpreter,
EmptyLocationRange,
true,
)
base = boundFunc.Base
boundAuth = boundFunc.BoundAuthorization
}
Expand Down Expand Up @@ -4147,7 +4151,7 @@ func (interpreter *Interpreter) newStorageIterationFunction(
interpreter,
storageValue,
functionType,
func(invocation Invocation) Value {
func(_ *SimpleCompositeValue, invocation Invocation) Value {
interpreter := invocation.Interpreter

fn, ok := invocation.Arguments[0].(FunctionValue)
Expand Down Expand Up @@ -4310,7 +4314,7 @@ func (interpreter *Interpreter) authAccountSaveFunction(
interpreter,
storageValue,
sema.Account_StorageTypeSaveFunctionType,
func(invocation Invocation) Value {
func(_ *SimpleCompositeValue, invocation Invocation) Value {
interpreter := invocation.Interpreter

value := invocation.Arguments[0]
Expand Down Expand Up @@ -4375,7 +4379,7 @@ func (interpreter *Interpreter) authAccountTypeFunction(
interpreter,
storageValue,
sema.Account_StorageTypeTypeFunctionType,
func(invocation Invocation) Value {
func(_ *SimpleCompositeValue, invocation Invocation) Value {
interpreter := invocation.Interpreter

path, ok := invocation.Arguments[0].(PathValue)
Expand Down Expand Up @@ -4433,7 +4437,7 @@ func (interpreter *Interpreter) authAccountReadFunction(
storageValue,
// same as sema.Account_StorageTypeCopyFunctionType
sema.Account_StorageTypeLoadFunctionType,
func(invocation Invocation) Value {
func(_ *SimpleCompositeValue, invocation Invocation) Value {
interpreter := invocation.Interpreter

path, ok := invocation.Arguments[0].(PathValue)
Expand Down Expand Up @@ -4517,7 +4521,7 @@ func (interpreter *Interpreter) authAccountBorrowFunction(
interpreter,
storageValue,
sema.Account_StorageTypeBorrowFunctionType,
func(invocation Invocation) Value {
func(_ *SimpleCompositeValue, invocation Invocation) Value {
interpreter := invocation.Interpreter

path, ok := invocation.Arguments[0].(PathValue)
Expand Down Expand Up @@ -4574,7 +4578,7 @@ func (interpreter *Interpreter) authAccountCheckFunction(
interpreter,
storageValue,
sema.Account_StorageTypeCheckFunctionType,
func(invocation Invocation) Value {
func(_ *SimpleCompositeValue, invocation Invocation) Value {
interpreter := invocation.Interpreter

path, ok := invocation.Arguments[0].(PathValue)
Expand Down Expand Up @@ -5043,7 +5047,14 @@ func (interpreter *Interpreter) mapMemberValueAuthorization(
case *StorageReferenceValue:
return NewStorageReferenceValue(interpreter, auth, refValue.TargetStorageAddress, refValue.TargetPath, refValue.BorrowedType)
case BoundFunctionValue:
return NewBoundFunctionValue(interpreter, refValue.Function, refValue.Self, refValue.Base, auth)
return NewBoundFunctionValueFromSelfReference(
interpreter,
refValue.Function,
refValue.SelfReference,
refValue.selfIsReference,
refValue.Base,
auth,
)
}
}
return resultValue
Expand Down Expand Up @@ -5098,7 +5109,7 @@ func (interpreter *Interpreter) isInstanceFunction(self Value) FunctionValue {
interpreter,
self,
sema.IsInstanceFunctionType,
func(invocation Invocation) Value {
func(self Value, invocation Invocation) Value {
interpreter := invocation.Interpreter

firstArgument := invocation.Arguments[0]
Expand Down Expand Up @@ -5129,7 +5140,7 @@ func (interpreter *Interpreter) getTypeFunction(self Value) FunctionValue {
interpreter,
self,
sema.GetTypeFunctionType,
func(invocation Invocation) Value {
func(self Value, invocation Invocation) Value {
interpreter := invocation.Interpreter
staticType := self.StaticType(interpreter)
return NewTypeValue(interpreter, staticType)
Expand Down Expand Up @@ -5566,7 +5577,7 @@ func (interpreter *Interpreter) capabilityBorrowFunction(
interpreter,
capabilityValue,
sema.CapabilityTypeBorrowFunctionType(capabilityBorrowType),
func(invocation Invocation) Value {
func(_ CapabilityValue, invocation Invocation) Value {

inter := invocation.Interpreter
locationRange := invocation.LocationRange
Expand Down Expand Up @@ -5613,7 +5624,7 @@ func (interpreter *Interpreter) capabilityCheckFunction(
interpreter,
capabilityValue,
sema.CapabilityTypeCheckFunctionType(capabilityBorrowType),
func(invocation Invocation) Value {
func(_ CapabilityValue, invocation Invocation) Value {

if capabilityID == InvalidCapabilityID {
return FalseValue
Expand Down
33 changes: 33 additions & 0 deletions runtime/interpreter/interpreter_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,39 @@ func (interpreter *Interpreter) visitInvocationExpressionWithImplicitArgument(in

interpreter.reportInvokedFunctionReturn()

locationRange := LocationRange{
Location: interpreter.Location,
HasPosition: invocationExpression.InvokedExpression,
}

functionReturnType := function.FunctionType().ReturnTypeAnnotation.Type

// Only convert and box.
// No need to transfer, since transfer would happen later, when the return value gets assigned.
//
// The conversion is needed because, the runtime function's return type could be a
// subtype of the invocation's return type.
// e.g:
// struct interface I {
// fun foo(): T?
// }
//
// struct S: I {
// fun foo(): T {...}
// }
//
// var i: {I} = S()
// return i.foo()?.bar
//
// Here runtime function's return type is `T`, but invocation's return type is `T?`.

resultValue = interpreter.ConvertAndBox(
locationRange,
resultValue,
functionReturnType,
invocationExpressionTypes.ReturnType,
)

// If this is invocation is optional chaining, wrap the result
// as an optional, as the result is expected to be an optional
if isOptionalChaining {
Expand Down
Loading

0 comments on commit 528b9ae

Please sign in to comment.