mirror of
https://github.com/hanzoai/expr.git
synced 2026-09-24 16:58:58 +00:00
Add spans
This commit is contained in:
@@ -50,6 +50,11 @@ func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err erro
|
||||
}
|
||||
}
|
||||
|
||||
var span *Span
|
||||
if len(c.spans) > 0 {
|
||||
span = c.spans[0]
|
||||
}
|
||||
|
||||
program = NewProgram(
|
||||
tree.Source,
|
||||
tree.Node,
|
||||
@@ -60,6 +65,7 @@ func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err erro
|
||||
c.arguments,
|
||||
c.functions,
|
||||
c.debugInfo,
|
||||
span,
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -76,6 +82,7 @@ type compiler struct {
|
||||
functionsIndex map[string]int
|
||||
debugInfo map[string]string
|
||||
nodes []ast.Node
|
||||
spans []*Span
|
||||
chains [][]int
|
||||
arguments []int
|
||||
}
|
||||
@@ -193,6 +200,28 @@ func (c *compiler) compile(node ast.Node) {
|
||||
c.nodes = c.nodes[:len(c.nodes)-1]
|
||||
}()
|
||||
|
||||
if c.config != nil && c.config.Profile {
|
||||
span := &Span{
|
||||
Name: reflect.TypeOf(node).String(),
|
||||
Expression: node.String(),
|
||||
}
|
||||
if len(c.spans) > 0 {
|
||||
prev := c.spans[len(c.spans)-1]
|
||||
prev.Children = append(prev.Children, span)
|
||||
}
|
||||
c.spans = append(c.spans, span)
|
||||
defer func() {
|
||||
if len(c.spans) > 1 {
|
||||
c.spans = c.spans[:len(c.spans)-1]
|
||||
}
|
||||
}()
|
||||
|
||||
c.emit(OpProfileStart, c.addConstant(span))
|
||||
defer func() {
|
||||
c.emit(OpProfileEnd, c.addConstant(span))
|
||||
}()
|
||||
}
|
||||
|
||||
switch n := node.(type) {
|
||||
case *ast.NilNode:
|
||||
c.NilNode(n)
|
||||
|
||||
@@ -20,6 +20,7 @@ type Config struct {
|
||||
ExpectAny bool
|
||||
Optimize bool
|
||||
Strict bool
|
||||
Profile bool
|
||||
ConstFns map[string]reflect.Value
|
||||
Visitors []ast.Visitor
|
||||
Functions FunctionsTable
|
||||
|
||||
@@ -81,6 +81,8 @@ const (
|
||||
OpGroupBy
|
||||
OpSortBy
|
||||
OpSort
|
||||
OpProfileStart
|
||||
OpProfileEnd
|
||||
OpBegin
|
||||
OpEnd // This opcode must be at the end of this list.
|
||||
)
|
||||
|
||||
@@ -27,6 +27,7 @@ type Program struct {
|
||||
variables int
|
||||
functions []Function
|
||||
debugInfo map[string]string
|
||||
span *Span
|
||||
}
|
||||
|
||||
// NewProgram returns a new Program. It's used by the compiler.
|
||||
@@ -40,6 +41,7 @@ func NewProgram(
|
||||
arguments []int,
|
||||
functions []Function,
|
||||
debugInfo map[string]string,
|
||||
span *Span,
|
||||
) *Program {
|
||||
return &Program{
|
||||
source: source,
|
||||
@@ -51,6 +53,7 @@ func NewProgram(
|
||||
Arguments: arguments,
|
||||
functions: functions,
|
||||
debugInfo: debugInfo,
|
||||
span: span,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,6 +363,12 @@ func (program *Program) DisassembleWriter(w io.Writer) {
|
||||
case OpSort:
|
||||
code("OpSort")
|
||||
|
||||
case OpProfileStart:
|
||||
code("OpProfileStart")
|
||||
|
||||
case OpProfileEnd:
|
||||
code("OpProfileEnd")
|
||||
|
||||
case OpBegin:
|
||||
code("OpBegin")
|
||||
|
||||
|
||||
+13
@@ -2,6 +2,7 @@ package vm
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -25,3 +26,15 @@ type Scope struct {
|
||||
}
|
||||
|
||||
type groupBy = map[any][]any
|
||||
|
||||
type Span struct {
|
||||
Name string `json:"name"`
|
||||
Expression string `json:"expression"`
|
||||
Duration int64 `json:"duration"`
|
||||
Children []*Span `json:"children"`
|
||||
start time.Time
|
||||
}
|
||||
|
||||
func GetSpan(program *Program) *Span {
|
||||
return program.span
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/expr-lang/expr/builtin"
|
||||
"github.com/expr-lang/expr/file"
|
||||
@@ -523,6 +524,14 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
|
||||
vm.memGrow(uint(scope.Len))
|
||||
vm.push(sortable.Array)
|
||||
|
||||
case OpProfileStart:
|
||||
span := program.Constants[arg].(*Span)
|
||||
span.start = time.Now()
|
||||
|
||||
case OpProfileEnd:
|
||||
span := program.Constants[arg].(*Span)
|
||||
span.Duration += time.Since(span.start).Nanoseconds()
|
||||
|
||||
case OpBegin:
|
||||
a := vm.pop()
|
||||
array := reflect.ValueOf(a)
|
||||
|
||||
Reference in New Issue
Block a user