Skip to content

Commit

Permalink
lang: ast: try to not use sub-graphs if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
gelisam committed Dec 16, 2023
1 parent 7b5466e commit a83a075
Showing 1 changed file with 33 additions and 14 deletions.
47 changes: 33 additions & 14 deletions lang/ast/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8191,6 +8191,39 @@ func (obj *ExprCall) Graph(env map[string]interfaces.Func) (*pgraph.Graph, inter
return nil, nil, errwrap.Wrapf(err, "could not get the type of the function")
}

// Loop over the arguments, add them to the graph, but do _not_ connect them
// to the function vertex. Instead, each time we need to generate a sub-graph
// (perhaps only once if the function expression is constant), the FuncValue
// (either that constant expression or a FuncValue which CallFunc receives
// from upstream) creates the corresponding subgraph and connects these
// arguments to it.
var argFuncs []interfaces.Func
for i, arg := range obj.Args {
argGraph, argFunc, err := arg.Graph(env)
if err != nil {
return nil, nil, errwrap.Wrapf(err, "could not get graph for arg %d", i)
}
graph.AddGraph(argGraph)
argFuncs = append(argFuncs, argFunc)
}

// if obj.expr is a CallableExpr and that expression is constant, then we
// don't need CallFunc because the same sub-graph will be used for the
// entirety of the execution. Instead, embed that sub-graph in the main graph.
staticValue, err := obj.expr.Value()
if staticValue != nil {
if fullFuncValue, isFuncValue := staticValue.(*full.FuncValue); isFuncValue {
// The function is constant, so we can embed the sub-graph directly.
fakeTxn := panic("TODO: create a txn which adds nodes to the graph")
outputFunc, err := fullFuncValue.Call(fakeTxn, argFuncs)
if err != nil {
return nil, nil, errwrap.Wrapf(err, "could not call the function")
}
graph.AddGraph(fakeTxn.Graph())
return graph, outputFunc, nil
}
}

// Find the vertex which produces the FuncValue.
var funcValueFunc interfaces.Func
if _, isParam := obj.expr.(*ExprParam); isParam {
Expand All @@ -8215,20 +8248,6 @@ func (obj *ExprCall) Graph(env map[string]interfaces.Func) (*pgraph.Graph, inter
funcValueFunc = topLevelFunc
}

// Loop over the arguments, add them to the graph, but do _not_ connect them
// to the function vertex. Instead, each time the call vertex (which we
// create below) receives a FuncValue from the function node, it creates the
// corresponding subgraph and connects these arguments to it.
var argFuncs []interfaces.Func
for i, arg := range obj.Args {
argGraph, argFunc, err := arg.Graph(env)
if err != nil {
return nil, nil, errwrap.Wrapf(err, "could not get graph for arg %d", i)
}
graph.AddGraph(argGraph)
argFuncs = append(argFuncs, argFunc)
}

// Add a vertex for the call itself.
edgeName := structs.CallFuncArgNameFunction
callFunc := &structs.CallFunc{
Expand Down

0 comments on commit a83a075

Please sign in to comment.