Skip to content

Commit

Permalink
add support for injecting types into the environment
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent committed Sep 22, 2023
1 parent 1b64714 commit 7cb1074
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 9 deletions.
21 changes: 15 additions & 6 deletions runtime/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import (
type Environment interface {
ArgumentDecoder

Declare(valueDeclaration stdlib.StandardLibraryValue)
DeclareValue(valueDeclaration stdlib.StandardLibraryValue)
DeclareType(typeDeclaration stdlib.StandardLibraryType)
Configure(
runtimeInterface Interface,
codesAndPrograms CodesAndPrograms,
Expand Down Expand Up @@ -78,8 +79,9 @@ type interpreterEnvironmentReconfigured struct {

type interpreterEnvironment struct {
interpreterEnvironmentReconfigured
baseActivation *interpreter.VariableActivation
baseTypeActivation *sema.VariableActivation
baseValueActivation *sema.VariableActivation
baseActivation *interpreter.VariableActivation
InterpreterConfig *interpreter.Config
CheckerConfig *sema.Config
deployedContractConstructorInvocation *stdlib.DeployedContractConstructorInvocation
Expand Down Expand Up @@ -108,12 +110,14 @@ var _ common.MemoryGauge = &interpreterEnvironment{}

func newInterpreterEnvironment(config Config) *interpreterEnvironment {
baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation)
baseTypeActivation := sema.NewVariableActivation(sema.BaseTypeActivation)
baseActivation := activations.NewActivation[*interpreter.Variable](nil, interpreter.BaseActivation)

env := &interpreterEnvironment{
config: config,
baseActivation: baseActivation,
baseValueActivation: baseValueActivation,
baseTypeActivation: baseTypeActivation,
baseActivation: baseActivation,
stackDepthLimiter: newStackDepthLimiter(config.StackDepthLimit),
}
env.InterpreterConfig = env.newInterpreterConfig()
Expand Down Expand Up @@ -158,6 +162,7 @@ func (e *interpreterEnvironment) newCheckerConfig() *sema.Config {
return &sema.Config{
AccessCheckMode: sema.AccessCheckModeStrict,
BaseValueActivation: e.baseValueActivation,
BaseTypeActivation: e.baseTypeActivation,
ValidTopLevelDeclarationsHandler: validTopLevelDeclarations,
LocationHandler: e.newLocationHandler(),
ImportHandler: e.resolveImport,
Expand All @@ -171,15 +176,15 @@ func (e *interpreterEnvironment) newCheckerConfig() *sema.Config {
func NewBaseInterpreterEnvironment(config Config) *interpreterEnvironment {
env := newInterpreterEnvironment(config)
for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(env) {
env.Declare(valueDeclaration)
env.DeclareValue(valueDeclaration)
}
return env
}

func NewScriptInterpreterEnvironment(config Config) Environment {
env := newInterpreterEnvironment(config)
for _, valueDeclaration := range stdlib.DefaultScriptStandardLibraryValues(env) {
env.Declare(valueDeclaration)
env.DeclareValue(valueDeclaration)
}
return env
}
Expand All @@ -198,11 +203,15 @@ func (e *interpreterEnvironment) Configure(
e.stackDepthLimiter.depth = 0
}

func (e *interpreterEnvironment) Declare(valueDeclaration stdlib.StandardLibraryValue) {
func (e *interpreterEnvironment) DeclareValue(valueDeclaration stdlib.StandardLibraryValue) {
e.baseValueActivation.DeclareValue(valueDeclaration)
interpreter.Declare(e.baseActivation, valueDeclaration)
}

func (e *interpreterEnvironment) DeclareType(typeDeclaration stdlib.StandardLibraryType) {
e.baseTypeActivation.DeclareType(typeDeclaration)
}

func (e *interpreterEnvironment) NewAuthAccountValue(address interpreter.AddressValue) interpreter.Value {
return stdlib.NewAuthAccountValue(e, e, address)
}
Expand Down
65 changes: 62 additions & 3 deletions runtime/predeclaredvalues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestRuntimePredeclaredValues(t *testing.T) {
valueDeclaration := stdlib.StandardLibraryValue{
Name: "foo",
Type: sema.IntType,
Kind: common.DeclarationKindFunction,
Kind: common.DeclarationKindConstant,
Value: interpreter.NewUnmeteredIntValueFromInt64(2),
}

Expand Down Expand Up @@ -91,7 +91,7 @@ func TestRuntimePredeclaredValues(t *testing.T) {
// Run transaction

transactionEnvironment := NewBaseInterpreterEnvironment(Config{})
transactionEnvironment.Declare(valueDeclaration)
transactionEnvironment.DeclareValue(valueDeclaration)

err := runtime.ExecuteTransaction(
Script{
Expand All @@ -108,7 +108,7 @@ func TestRuntimePredeclaredValues(t *testing.T) {
// Run script

scriptEnvironment := NewScriptInterpreterEnvironment(Config{})
scriptEnvironment.Declare(valueDeclaration)
scriptEnvironment.DeclareValue(valueDeclaration)

result, err := runtime.ExecuteScript(
Script{
Expand All @@ -127,3 +127,62 @@ func TestRuntimePredeclaredValues(t *testing.T) {
result,
)
}

func TestRuntimePredeclaredTypes(t *testing.T) {

t.Parallel()

xType := sema.IntType

valueDeclaration := stdlib.StandardLibraryValue{
Name: "x",
Type: xType,
Kind: common.DeclarationKindConstant,
Value: interpreter.NewUnmeteredIntValueFromInt64(2),
}

typeDeclaration := stdlib.StandardLibraryType{
Name: "X",
Type: xType,
Kind: common.DeclarationKindType,
}

script := []byte(`
pub fun main(): X {
return x
}
`)

runtime := newTestInterpreterRuntime()

runtimeInterface := &testRuntimeInterface{
storage: newTestLedger(nil, nil),
getSigningAccounts: func() ([]Address, error) {
return []Address{common.MustBytesToAddress([]byte{0x1})}, nil
},
resolveLocation: singleIdentifierLocationResolver(t),
}

// Run script

scriptEnvironment := NewScriptInterpreterEnvironment(Config{})
scriptEnvironment.DeclareValue(valueDeclaration)
scriptEnvironment.DeclareType(typeDeclaration)

result, err := runtime.ExecuteScript(
Script{
Source: script,
},
Context{
Interface: runtimeInterface,
Location: common.ScriptLocation{},
Environment: scriptEnvironment,
},
)
require.NoError(t, err)

require.Equal(t,
cadence.Int{Value: big.NewInt(2)},
result,
)
}

0 comments on commit 7cb1074

Please sign in to comment.