chore: upgrade coredns version (#550)

This commit is contained in:
naison
2025-04-19 10:06:56 +08:00
committed by GitHub
parent c42e3475f9
commit c9f1ce6522
1701 changed files with 235209 additions and 29271 deletions

6
vendor/github.com/expr-lang/expr/vm/debug.go generated vendored Normal file
View File

@@ -0,0 +1,6 @@
//go:build expr_debug
// +build expr_debug
package vm
const debug = true

6
vendor/github.com/expr-lang/expr/vm/debug_off.go generated vendored Normal file
View File

@@ -0,0 +1,6 @@
//go:build !expr_debug
// +build !expr_debug
package vm
const debug = false

View File

@@ -0,0 +1,370 @@
// Code generated by vm/func_types/main.go. DO NOT EDIT.
package vm
import (
"fmt"
"time"
)
var FuncTypes = []any{
1: new(func() time.Duration),
2: new(func() time.Month),
3: new(func() time.Time),
4: new(func() time.Weekday),
5: new(func() []interface{}),
6: new(func() []uint8),
7: new(func() interface{}),
8: new(func() bool),
9: new(func() uint8),
10: new(func() float32),
11: new(func() float64),
12: new(func() int),
13: new(func() int16),
14: new(func() int32),
15: new(func() int64),
16: new(func() int8),
17: new(func() map[string]interface{}),
18: new(func() int32),
19: new(func() string),
20: new(func() uint),
21: new(func() uint16),
22: new(func() uint32),
23: new(func() uint64),
24: new(func() uint8),
25: new(func(time.Duration) time.Duration),
26: new(func(time.Duration) time.Time),
27: new(func(time.Time) time.Duration),
28: new(func(time.Time) bool),
29: new(func([]interface{}) []interface{}),
30: new(func([]interface{}) interface{}),
31: new(func([]interface{}) map[string]interface{}),
32: new(func([]interface{}, string) string),
33: new(func([]uint8) string),
34: new(func([]string, string) string),
35: new(func(interface{}) []interface{}),
36: new(func(interface{}) interface{}),
37: new(func(interface{}) bool),
38: new(func(interface{}) float64),
39: new(func(interface{}) int),
40: new(func(interface{}) map[string]interface{}),
41: new(func(interface{}) string),
42: new(func(interface{}, interface{}) []interface{}),
43: new(func(interface{}, interface{}) interface{}),
44: new(func(interface{}, interface{}) bool),
45: new(func(interface{}, interface{}) string),
46: new(func(bool) bool),
47: new(func(bool) float64),
48: new(func(bool) int),
49: new(func(bool) string),
50: new(func(bool, bool) bool),
51: new(func(float32) float64),
52: new(func(float64) bool),
53: new(func(float64) float32),
54: new(func(float64) float64),
55: new(func(float64) int),
56: new(func(float64) string),
57: new(func(float64, float64) bool),
58: new(func(int) bool),
59: new(func(int) float64),
60: new(func(int) int),
61: new(func(int) string),
62: new(func(int, int) bool),
63: new(func(int, int) int),
64: new(func(int, int) string),
65: new(func(int16) int32),
66: new(func(int32) float64),
67: new(func(int32) int),
68: new(func(int32) int64),
69: new(func(int64) time.Time),
70: new(func(int8) int),
71: new(func(int8) int16),
72: new(func(string) []uint8),
73: new(func(string) []string),
74: new(func(string) bool),
75: new(func(string) float64),
76: new(func(string) int),
77: new(func(string) string),
78: new(func(string, uint8) int),
79: new(func(string, int) int),
80: new(func(string, int32) int),
81: new(func(string, string) bool),
82: new(func(string, string) string),
83: new(func(uint) float64),
84: new(func(uint) int),
85: new(func(uint) uint),
86: new(func(uint16) uint),
87: new(func(uint32) uint64),
88: new(func(uint64) float64),
89: new(func(uint64) int64),
90: new(func(uint8) uint8),
}
func (vm *VM) call(fn any, kind int) any {
switch kind {
case 1:
return fn.(func() time.Duration)()
case 2:
return fn.(func() time.Month)()
case 3:
return fn.(func() time.Time)()
case 4:
return fn.(func() time.Weekday)()
case 5:
return fn.(func() []interface{})()
case 6:
return fn.(func() []uint8)()
case 7:
return fn.(func() interface{})()
case 8:
return fn.(func() bool)()
case 9:
return fn.(func() uint8)()
case 10:
return fn.(func() float32)()
case 11:
return fn.(func() float64)()
case 12:
return fn.(func() int)()
case 13:
return fn.(func() int16)()
case 14:
return fn.(func() int32)()
case 15:
return fn.(func() int64)()
case 16:
return fn.(func() int8)()
case 17:
return fn.(func() map[string]interface{})()
case 18:
return fn.(func() int32)()
case 19:
return fn.(func() string)()
case 20:
return fn.(func() uint)()
case 21:
return fn.(func() uint16)()
case 22:
return fn.(func() uint32)()
case 23:
return fn.(func() uint64)()
case 24:
return fn.(func() uint8)()
case 25:
arg1 := vm.pop().(time.Duration)
return fn.(func(time.Duration) time.Duration)(arg1)
case 26:
arg1 := vm.pop().(time.Duration)
return fn.(func(time.Duration) time.Time)(arg1)
case 27:
arg1 := vm.pop().(time.Time)
return fn.(func(time.Time) time.Duration)(arg1)
case 28:
arg1 := vm.pop().(time.Time)
return fn.(func(time.Time) bool)(arg1)
case 29:
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}) []interface{})(arg1)
case 30:
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}) interface{})(arg1)
case 31:
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}) map[string]interface{})(arg1)
case 32:
arg2 := vm.pop().(string)
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}, string) string)(arg1, arg2)
case 33:
arg1 := vm.pop().([]uint8)
return fn.(func([]uint8) string)(arg1)
case 34:
arg2 := vm.pop().(string)
arg1 := vm.pop().([]string)
return fn.(func([]string, string) string)(arg1, arg2)
case 35:
arg1 := vm.pop()
return fn.(func(interface{}) []interface{})(arg1)
case 36:
arg1 := vm.pop()
return fn.(func(interface{}) interface{})(arg1)
case 37:
arg1 := vm.pop()
return fn.(func(interface{}) bool)(arg1)
case 38:
arg1 := vm.pop()
return fn.(func(interface{}) float64)(arg1)
case 39:
arg1 := vm.pop()
return fn.(func(interface{}) int)(arg1)
case 40:
arg1 := vm.pop()
return fn.(func(interface{}) map[string]interface{})(arg1)
case 41:
arg1 := vm.pop()
return fn.(func(interface{}) string)(arg1)
case 42:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) []interface{})(arg1, arg2)
case 43:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) interface{})(arg1, arg2)
case 44:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) bool)(arg1, arg2)
case 45:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) string)(arg1, arg2)
case 46:
arg1 := vm.pop().(bool)
return fn.(func(bool) bool)(arg1)
case 47:
arg1 := vm.pop().(bool)
return fn.(func(bool) float64)(arg1)
case 48:
arg1 := vm.pop().(bool)
return fn.(func(bool) int)(arg1)
case 49:
arg1 := vm.pop().(bool)
return fn.(func(bool) string)(arg1)
case 50:
arg2 := vm.pop().(bool)
arg1 := vm.pop().(bool)
return fn.(func(bool, bool) bool)(arg1, arg2)
case 51:
arg1 := vm.pop().(float32)
return fn.(func(float32) float64)(arg1)
case 52:
arg1 := vm.pop().(float64)
return fn.(func(float64) bool)(arg1)
case 53:
arg1 := vm.pop().(float64)
return fn.(func(float64) float32)(arg1)
case 54:
arg1 := vm.pop().(float64)
return fn.(func(float64) float64)(arg1)
case 55:
arg1 := vm.pop().(float64)
return fn.(func(float64) int)(arg1)
case 56:
arg1 := vm.pop().(float64)
return fn.(func(float64) string)(arg1)
case 57:
arg2 := vm.pop().(float64)
arg1 := vm.pop().(float64)
return fn.(func(float64, float64) bool)(arg1, arg2)
case 58:
arg1 := vm.pop().(int)
return fn.(func(int) bool)(arg1)
case 59:
arg1 := vm.pop().(int)
return fn.(func(int) float64)(arg1)
case 60:
arg1 := vm.pop().(int)
return fn.(func(int) int)(arg1)
case 61:
arg1 := vm.pop().(int)
return fn.(func(int) string)(arg1)
case 62:
arg2 := vm.pop().(int)
arg1 := vm.pop().(int)
return fn.(func(int, int) bool)(arg1, arg2)
case 63:
arg2 := vm.pop().(int)
arg1 := vm.pop().(int)
return fn.(func(int, int) int)(arg1, arg2)
case 64:
arg2 := vm.pop().(int)
arg1 := vm.pop().(int)
return fn.(func(int, int) string)(arg1, arg2)
case 65:
arg1 := vm.pop().(int16)
return fn.(func(int16) int32)(arg1)
case 66:
arg1 := vm.pop().(int32)
return fn.(func(int32) float64)(arg1)
case 67:
arg1 := vm.pop().(int32)
return fn.(func(int32) int)(arg1)
case 68:
arg1 := vm.pop().(int32)
return fn.(func(int32) int64)(arg1)
case 69:
arg1 := vm.pop().(int64)
return fn.(func(int64) time.Time)(arg1)
case 70:
arg1 := vm.pop().(int8)
return fn.(func(int8) int)(arg1)
case 71:
arg1 := vm.pop().(int8)
return fn.(func(int8) int16)(arg1)
case 72:
arg1 := vm.pop().(string)
return fn.(func(string) []uint8)(arg1)
case 73:
arg1 := vm.pop().(string)
return fn.(func(string) []string)(arg1)
case 74:
arg1 := vm.pop().(string)
return fn.(func(string) bool)(arg1)
case 75:
arg1 := vm.pop().(string)
return fn.(func(string) float64)(arg1)
case 76:
arg1 := vm.pop().(string)
return fn.(func(string) int)(arg1)
case 77:
arg1 := vm.pop().(string)
return fn.(func(string) string)(arg1)
case 78:
arg2 := vm.pop().(uint8)
arg1 := vm.pop().(string)
return fn.(func(string, uint8) int)(arg1, arg2)
case 79:
arg2 := vm.pop().(int)
arg1 := vm.pop().(string)
return fn.(func(string, int) int)(arg1, arg2)
case 80:
arg2 := vm.pop().(int32)
arg1 := vm.pop().(string)
return fn.(func(string, int32) int)(arg1, arg2)
case 81:
arg2 := vm.pop().(string)
arg1 := vm.pop().(string)
return fn.(func(string, string) bool)(arg1, arg2)
case 82:
arg2 := vm.pop().(string)
arg1 := vm.pop().(string)
return fn.(func(string, string) string)(arg1, arg2)
case 83:
arg1 := vm.pop().(uint)
return fn.(func(uint) float64)(arg1)
case 84:
arg1 := vm.pop().(uint)
return fn.(func(uint) int)(arg1)
case 85:
arg1 := vm.pop().(uint)
return fn.(func(uint) uint)(arg1)
case 86:
arg1 := vm.pop().(uint16)
return fn.(func(uint16) uint)(arg1)
case 87:
arg1 := vm.pop().(uint32)
return fn.(func(uint32) uint64)(arg1)
case 88:
arg1 := vm.pop().(uint64)
return fn.(func(uint64) float64)(arg1)
case 89:
arg1 := vm.pop().(uint64)
return fn.(func(uint64) int64)(arg1)
case 90:
arg1 := vm.pop().(uint8)
return fn.(func(uint8) uint8)(arg1)
}
panic(fmt.Sprintf("unknown function kind (%v)", kind))
}

88
vendor/github.com/expr-lang/expr/vm/opcodes.go generated vendored Normal file
View File

@@ -0,0 +1,88 @@
package vm
type Opcode byte
const (
OpInvalid Opcode = iota
OpPush
OpInt
OpPop
OpStore
OpLoadVar
OpLoadConst
OpLoadField
OpLoadFast
OpLoadMethod
OpLoadFunc
OpLoadEnv
OpFetch
OpFetchField
OpMethod
OpTrue
OpFalse
OpNil
OpNegate
OpNot
OpEqual
OpEqualInt
OpEqualString
OpJump
OpJumpIfTrue
OpJumpIfFalse
OpJumpIfNil
OpJumpIfNotNil
OpJumpIfEnd
OpJumpBackward
OpIn
OpLess
OpMore
OpLessOrEqual
OpMoreOrEqual
OpAdd
OpSubtract
OpMultiply
OpDivide
OpModulo
OpExponent
OpRange
OpMatches
OpMatchesConst
OpContains
OpStartsWith
OpEndsWith
OpSlice
OpCall
OpCall0
OpCall1
OpCall2
OpCall3
OpCallN
OpCallFast
OpCallSafe
OpCallTyped
OpCallBuiltin1
OpArray
OpMap
OpLen
OpCast
OpDeref
OpIncrementIndex
OpDecrementIndex
OpIncrementCount
OpGetIndex
OpGetCount
OpGetLen
OpGetAcc
OpSetAcc
OpSetIndex
OpPointer
OpThrow
OpCreate
OpGroupBy
OpSortBy
OpSort
OpProfileStart
OpProfileEnd
OpBegin
OpEnd // This opcode must be at the end of this list.
)

382
vendor/github.com/expr-lang/expr/vm/program.go generated vendored Normal file
View File

@@ -0,0 +1,382 @@
package vm
import (
"bytes"
"fmt"
"io"
"reflect"
"regexp"
"strings"
"text/tabwriter"
"github.com/expr-lang/expr/ast"
"github.com/expr-lang/expr/builtin"
"github.com/expr-lang/expr/file"
"github.com/expr-lang/expr/vm/runtime"
)
// Program represents a compiled expression.
type Program struct {
Bytecode []Opcode
Arguments []int
Constants []any
source file.Source
node ast.Node
locations []file.Location
variables int
functions []Function
debugInfo map[string]string
span *Span
}
// NewProgram returns a new Program. It's used by the compiler.
func NewProgram(
source file.Source,
node ast.Node,
locations []file.Location,
variables int,
constants []any,
bytecode []Opcode,
arguments []int,
functions []Function,
debugInfo map[string]string,
span *Span,
) *Program {
return &Program{
source: source,
node: node,
locations: locations,
variables: variables,
Constants: constants,
Bytecode: bytecode,
Arguments: arguments,
functions: functions,
debugInfo: debugInfo,
span: span,
}
}
// Source returns origin file.Source.
func (program *Program) Source() file.Source {
return program.source
}
// Node returns origin ast.Node.
func (program *Program) Node() ast.Node {
return program.node
}
// Locations returns a slice of bytecode's locations.
func (program *Program) Locations() []file.Location {
return program.locations
}
// Disassemble returns opcodes as a string.
func (program *Program) Disassemble() string {
var buf bytes.Buffer
w := tabwriter.NewWriter(&buf, 0, 0, 2, ' ', 0)
program.DisassembleWriter(w)
_ = w.Flush()
return buf.String()
}
// DisassembleWriter takes a writer and writes opcodes to it.
func (program *Program) DisassembleWriter(w io.Writer) {
ip := 0
for ip < len(program.Bytecode) {
pp := ip
op := program.Bytecode[ip]
arg := program.Arguments[ip]
ip += 1
code := func(label string) {
_, _ = fmt.Fprintf(w, "%v\t%v\n", pp, label)
}
jump := func(label string) {
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t(%v)\n", pp, label, arg, ip+arg)
}
jumpBack := func(label string) {
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t(%v)\n", pp, label, arg, ip-arg)
}
argument := func(label string) {
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\n", pp, label, arg)
}
argumentWithInfo := func(label string, prefix string) {
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, program.debugInfo[fmt.Sprintf("%s_%d", prefix, arg)])
}
constant := func(label string) {
var c any
if arg < len(program.Constants) {
c = program.Constants[arg]
} else {
c = "out of range"
}
if r, ok := c.(*regexp.Regexp); ok {
c = r.String()
}
if field, ok := c.(*runtime.Field); ok {
c = fmt.Sprintf("{%v %v}", strings.Join(field.Path, "."), field.Index)
}
if method, ok := c.(*runtime.Method); ok {
c = fmt.Sprintf("{%v %v}", method.Name, method.Index)
}
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, c)
}
builtinArg := func(label string) {
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, builtin.Builtins[arg].Name)
}
switch op {
case OpInvalid:
code("OpInvalid")
case OpPush:
constant("OpPush")
case OpInt:
argument("OpInt")
case OpPop:
code("OpPop")
case OpStore:
argumentWithInfo("OpStore", "var")
case OpLoadVar:
argumentWithInfo("OpLoadVar", "var")
case OpLoadConst:
constant("OpLoadConst")
case OpLoadField:
constant("OpLoadField")
case OpLoadFast:
constant("OpLoadFast")
case OpLoadMethod:
constant("OpLoadMethod")
case OpLoadFunc:
argumentWithInfo("OpLoadFunc", "func")
case OpLoadEnv:
code("OpLoadEnv")
case OpFetch:
code("OpFetch")
case OpFetchField:
constant("OpFetchField")
case OpMethod:
constant("OpMethod")
case OpTrue:
code("OpTrue")
case OpFalse:
code("OpFalse")
case OpNil:
code("OpNil")
case OpNegate:
code("OpNegate")
case OpNot:
code("OpNot")
case OpEqual:
code("OpEqual")
case OpEqualInt:
code("OpEqualInt")
case OpEqualString:
code("OpEqualString")
case OpJump:
jump("OpJump")
case OpJumpIfTrue:
jump("OpJumpIfTrue")
case OpJumpIfFalse:
jump("OpJumpIfFalse")
case OpJumpIfNil:
jump("OpJumpIfNil")
case OpJumpIfNotNil:
jump("OpJumpIfNotNil")
case OpJumpIfEnd:
jump("OpJumpIfEnd")
case OpJumpBackward:
jumpBack("OpJumpBackward")
case OpIn:
code("OpIn")
case OpLess:
code("OpLess")
case OpMore:
code("OpMore")
case OpLessOrEqual:
code("OpLessOrEqual")
case OpMoreOrEqual:
code("OpMoreOrEqual")
case OpAdd:
code("OpAdd")
case OpSubtract:
code("OpSubtract")
case OpMultiply:
code("OpMultiply")
case OpDivide:
code("OpDivide")
case OpModulo:
code("OpModulo")
case OpExponent:
code("OpExponent")
case OpRange:
code("OpRange")
case OpMatches:
code("OpMatches")
case OpMatchesConst:
constant("OpMatchesConst")
case OpContains:
code("OpContains")
case OpStartsWith:
code("OpStartsWith")
case OpEndsWith:
code("OpEndsWith")
case OpSlice:
code("OpSlice")
case OpCall:
argument("OpCall")
case OpCall0:
argumentWithInfo("OpCall0", "func")
case OpCall1:
argumentWithInfo("OpCall1", "func")
case OpCall2:
argumentWithInfo("OpCall2", "func")
case OpCall3:
argumentWithInfo("OpCall3", "func")
case OpCallN:
argument("OpCallN")
case OpCallFast:
argument("OpCallFast")
case OpCallSafe:
argument("OpCallSafe")
case OpCallTyped:
signature := reflect.TypeOf(FuncTypes[arg]).Elem().String()
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, "OpCallTyped", arg, signature)
case OpCallBuiltin1:
builtinArg("OpCallBuiltin1")
case OpArray:
code("OpArray")
case OpMap:
code("OpMap")
case OpLen:
code("OpLen")
case OpCast:
argument("OpCast")
case OpDeref:
code("OpDeref")
case OpIncrementIndex:
code("OpIncrementIndex")
case OpDecrementIndex:
code("OpDecrementIndex")
case OpIncrementCount:
code("OpIncrementCount")
case OpGetIndex:
code("OpGetIndex")
case OpGetCount:
code("OpGetCount")
case OpGetLen:
code("OpGetLen")
case OpGetAcc:
code("OpGetAcc")
case OpSetAcc:
code("OpSetAcc")
case OpSetIndex:
code("OpSetIndex")
case OpPointer:
code("OpPointer")
case OpThrow:
code("OpThrow")
case OpCreate:
argument("OpCreate")
case OpGroupBy:
code("OpGroupBy")
case OpSortBy:
code("OpSortBy")
case OpSort:
code("OpSort")
case OpProfileStart:
code("OpProfileStart")
case OpProfileEnd:
code("OpProfileEnd")
case OpBegin:
code("OpBegin")
case OpEnd:
code("OpEnd")
default:
_, _ = fmt.Fprintf(w, "%v\t%#x (unknown)\n", ip, op)
}
}
}

File diff suppressed because it is too large Load Diff

394
vendor/github.com/expr-lang/expr/vm/runtime/runtime.go generated vendored Normal file
View File

@@ -0,0 +1,394 @@
package runtime
//go:generate sh -c "go run ./helpers > ./helpers[generated].go"
import (
"fmt"
"math"
"reflect"
"github.com/expr-lang/expr/internal/deref"
)
func Fetch(from, i any) any {
v := reflect.ValueOf(from)
if v.Kind() == reflect.Invalid {
panic(fmt.Sprintf("cannot fetch %v from %T", i, from))
}
// Methods can be defined on any type.
if v.NumMethod() > 0 {
if methodName, ok := i.(string); ok {
method := v.MethodByName(methodName)
if method.IsValid() {
return method.Interface()
}
}
}
// Structs, maps, and slices can be access through a pointer or through
// a value, when they are accessed through a pointer we don't want to
// copy them to a value.
// De-reference everything if necessary (interface and pointers)
v = deref.Value(v)
switch v.Kind() {
case reflect.Array, reflect.Slice, reflect.String:
index := ToInt(i)
l := v.Len()
if index < 0 {
index = l + index
}
if index < 0 || index >= l {
panic(fmt.Sprintf("index out of range: %v (array length is %v)", index, l))
}
value := v.Index(index)
if value.IsValid() {
return value.Interface()
}
case reflect.Map:
var value reflect.Value
if i == nil {
value = v.MapIndex(reflect.Zero(v.Type().Key()))
} else {
value = v.MapIndex(reflect.ValueOf(i))
}
if value.IsValid() {
return value.Interface()
} else {
elem := reflect.TypeOf(from).Elem()
return reflect.Zero(elem).Interface()
}
case reflect.Struct:
fieldName := i.(string)
value := v.FieldByNameFunc(func(name string) bool {
field, _ := v.Type().FieldByName(name)
if field.Tag.Get("expr") == fieldName {
return true
}
return name == fieldName
})
if value.IsValid() {
return value.Interface()
}
}
panic(fmt.Sprintf("cannot fetch %v from %T", i, from))
}
type Field struct {
Index []int
Path []string
}
func FetchField(from any, field *Field) any {
v := reflect.ValueOf(from)
if v.Kind() != reflect.Invalid {
v = reflect.Indirect(v)
// We can use v.FieldByIndex here, but it will panic if the field
// is not exists. And we need to recover() to generate a more
// user-friendly error message.
// Also, our fieldByIndex() function is slightly faster than the
// v.FieldByIndex() function as we don't need to verify what a field
// is a struct as we already did it on compilation step.
value := fieldByIndex(v, field)
if value.IsValid() {
return value.Interface()
}
}
panic(fmt.Sprintf("cannot get %v from %T", field.Path[0], from))
}
func fieldByIndex(v reflect.Value, field *Field) reflect.Value {
if len(field.Index) == 1 {
return v.Field(field.Index[0])
}
for i, x := range field.Index {
if i > 0 {
if v.Kind() == reflect.Ptr {
if v.IsNil() {
panic(fmt.Sprintf("cannot get %v from %v", field.Path[i], field.Path[i-1]))
}
v = v.Elem()
}
}
v = v.Field(x)
}
return v
}
type Method struct {
Index int
Name string
}
func FetchMethod(from any, method *Method) any {
v := reflect.ValueOf(from)
kind := v.Kind()
if kind != reflect.Invalid {
// Methods can be defined on any type, no need to dereference.
method := v.Method(method.Index)
if method.IsValid() {
return method.Interface()
}
}
panic(fmt.Sprintf("cannot fetch %v from %T", method.Name, from))
}
func Slice(array, from, to any) any {
v := reflect.ValueOf(array)
switch v.Kind() {
case reflect.Array, reflect.Slice, reflect.String:
length := v.Len()
a, b := ToInt(from), ToInt(to)
if a < 0 {
a = length + a
}
if a < 0 {
a = 0
}
if b < 0 {
b = length + b
}
if b < 0 {
b = 0
}
if b > length {
b = length
}
if a > b {
a = b
}
value := v.Slice(a, b)
if value.IsValid() {
return value.Interface()
}
case reflect.Ptr:
value := v.Elem()
if value.IsValid() {
return Slice(value.Interface(), from, to)
}
}
panic(fmt.Sprintf("cannot slice %v", from))
}
func In(needle any, array any) bool {
if array == nil {
return false
}
v := reflect.ValueOf(array)
switch v.Kind() {
case reflect.Array, reflect.Slice:
for i := 0; i < v.Len(); i++ {
value := v.Index(i)
if value.IsValid() {
if Equal(value.Interface(), needle) {
return true
}
}
}
return false
case reflect.Map:
var value reflect.Value
if needle == nil {
value = v.MapIndex(reflect.Zero(v.Type().Key()))
} else {
value = v.MapIndex(reflect.ValueOf(needle))
}
if value.IsValid() {
return true
}
return false
case reflect.Struct:
n := reflect.ValueOf(needle)
if !n.IsValid() || n.Kind() != reflect.String {
panic(fmt.Sprintf("cannot use %T as field name of %T", needle, array))
}
value := v.FieldByName(n.String())
if value.IsValid() {
return true
}
return false
case reflect.Ptr:
value := v.Elem()
if value.IsValid() {
return In(needle, value.Interface())
}
return false
}
panic(fmt.Sprintf(`operator "in" not defined on %T`, array))
}
func Len(a any) int {
v := reflect.ValueOf(a)
switch v.Kind() {
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
return v.Len()
default:
panic(fmt.Sprintf("invalid argument for len (type %T)", a))
}
}
func Negate(i any) any {
switch v := i.(type) {
case float32:
return -v
case float64:
return -v
case int:
return -v
case int8:
return -v
case int16:
return -v
case int32:
return -v
case int64:
return -v
case uint:
return -v
case uint8:
return -v
case uint16:
return -v
case uint32:
return -v
case uint64:
return -v
default:
panic(fmt.Sprintf("invalid operation: - %T", v))
}
}
func Exponent(a, b any) float64 {
return math.Pow(ToFloat64(a), ToFloat64(b))
}
func MakeRange(min, max int) []int {
size := max - min + 1
if size <= 0 {
return []int{}
}
rng := make([]int, size)
for i := range rng {
rng[i] = min + i
}
return rng
}
func ToInt(a any) int {
switch x := a.(type) {
case float32:
return int(x)
case float64:
return int(x)
case int:
return x
case int8:
return int(x)
case int16:
return int(x)
case int32:
return int(x)
case int64:
return int(x)
case uint:
return int(x)
case uint8:
return int(x)
case uint16:
return int(x)
case uint32:
return int(x)
case uint64:
return int(x)
default:
panic(fmt.Sprintf("invalid operation: int(%T)", x))
}
}
func ToInt64(a any) int64 {
switch x := a.(type) {
case float32:
return int64(x)
case float64:
return int64(x)
case int:
return int64(x)
case int8:
return int64(x)
case int16:
return int64(x)
case int32:
return int64(x)
case int64:
return x
case uint:
return int64(x)
case uint8:
return int64(x)
case uint16:
return int64(x)
case uint32:
return int64(x)
case uint64:
return int64(x)
default:
panic(fmt.Sprintf("invalid operation: int64(%T)", x))
}
}
func ToFloat64(a any) float64 {
switch x := a.(type) {
case float32:
return float64(x)
case float64:
return x
case int:
return float64(x)
case int8:
return float64(x)
case int16:
return float64(x)
case int32:
return float64(x)
case int64:
return float64(x)
case uint:
return float64(x)
case uint8:
return float64(x)
case uint16:
return float64(x)
case uint32:
return float64(x)
case uint64:
return float64(x)
default:
panic(fmt.Sprintf("invalid operation: float(%T)", x))
}
}
func IsNil(v any) bool {
if v == nil {
return true
}
r := reflect.ValueOf(v)
switch r.Kind() {
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice:
return r.IsNil()
default:
return false
}
}

45
vendor/github.com/expr-lang/expr/vm/runtime/sort.go generated vendored Normal file
View File

@@ -0,0 +1,45 @@
package runtime
type SortBy struct {
Desc bool
Array []any
Values []any
}
func (s *SortBy) Len() int {
return len(s.Array)
}
func (s *SortBy) Swap(i, j int) {
s.Array[i], s.Array[j] = s.Array[j], s.Array[i]
s.Values[i], s.Values[j] = s.Values[j], s.Values[i]
}
func (s *SortBy) Less(i, j int) bool {
a, b := s.Values[i], s.Values[j]
if s.Desc {
return Less(b, a)
}
return Less(a, b)
}
type Sort struct {
Desc bool
Array []any
}
func (s *Sort) Len() int {
return len(s.Array)
}
func (s *Sort) Swap(i, j int) {
s.Array[i], s.Array[j] = s.Array[j], s.Array[i]
}
func (s *Sort) Less(i, j int) bool {
a, b := s.Array[i], s.Array[j]
if s.Desc {
return Less(b, a)
}
return Less(a, b)
}

37
vendor/github.com/expr-lang/expr/vm/utils.go generated vendored Normal file
View File

@@ -0,0 +1,37 @@
package vm
import (
"reflect"
"time"
)
type (
Function = func(params ...any) (any, error)
SafeFunction = func(params ...any) (any, uint, error)
)
var (
errorType = reflect.TypeOf((*error)(nil)).Elem()
)
type Scope struct {
Array reflect.Value
Index int
Len int
Count int
Acc any
}
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
}

617
vendor/github.com/expr-lang/expr/vm/vm.go generated vendored Normal file
View File

@@ -0,0 +1,617 @@
package vm
//go:generate sh -c "go run ./func_types > ./func_types[generated].go"
import (
"fmt"
"reflect"
"regexp"
"sort"
"strings"
"time"
"github.com/expr-lang/expr/builtin"
"github.com/expr-lang/expr/conf"
"github.com/expr-lang/expr/file"
"github.com/expr-lang/expr/internal/deref"
"github.com/expr-lang/expr/vm/runtime"
)
func Run(program *Program, env any) (any, error) {
if program == nil {
return nil, fmt.Errorf("program is nil")
}
vm := VM{}
return vm.Run(program, env)
}
func Debug() *VM {
vm := &VM{
debug: true,
step: make(chan struct{}, 0),
curr: make(chan int, 0),
}
return vm
}
type VM struct {
Stack []any
Scopes []*Scope
Variables []any
MemoryBudget uint
ip int
memory uint
debug bool
step chan struct{}
curr chan int
}
func (vm *VM) Run(program *Program, env any) (_ any, err error) {
defer func() {
if r := recover(); r != nil {
var location file.Location
if vm.ip-1 < len(program.locations) {
location = program.locations[vm.ip-1]
}
f := &file.Error{
Location: location,
Message: fmt.Sprintf("%v", r),
}
if err, ok := r.(error); ok {
f.Wrap(err)
}
err = f.Bind(program.source)
}
}()
if vm.Stack == nil {
vm.Stack = make([]any, 0, 2)
} else {
vm.Stack = vm.Stack[0:0]
}
if vm.Scopes != nil {
vm.Scopes = vm.Scopes[0:0]
}
if len(vm.Variables) < program.variables {
vm.Variables = make([]any, program.variables)
}
if vm.MemoryBudget == 0 {
vm.MemoryBudget = conf.DefaultMemoryBudget
}
vm.memory = 0
vm.ip = 0
for vm.ip < len(program.Bytecode) {
if debug && vm.debug {
<-vm.step
}
op := program.Bytecode[vm.ip]
arg := program.Arguments[vm.ip]
vm.ip += 1
switch op {
case OpInvalid:
panic("invalid opcode")
case OpPush:
vm.push(program.Constants[arg])
case OpInt:
vm.push(arg)
case OpPop:
vm.pop()
case OpStore:
vm.Variables[arg] = vm.pop()
case OpLoadVar:
vm.push(vm.Variables[arg])
case OpLoadConst:
vm.push(runtime.Fetch(env, program.Constants[arg]))
case OpLoadField:
vm.push(runtime.FetchField(env, program.Constants[arg].(*runtime.Field)))
case OpLoadFast:
vm.push(env.(map[string]any)[program.Constants[arg].(string)])
case OpLoadMethod:
vm.push(runtime.FetchMethod(env, program.Constants[arg].(*runtime.Method)))
case OpLoadFunc:
vm.push(program.functions[arg])
case OpFetch:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Fetch(a, b))
case OpFetchField:
a := vm.pop()
vm.push(runtime.FetchField(a, program.Constants[arg].(*runtime.Field)))
case OpLoadEnv:
vm.push(env)
case OpMethod:
a := vm.pop()
vm.push(runtime.FetchMethod(a, program.Constants[arg].(*runtime.Method)))
case OpTrue:
vm.push(true)
case OpFalse:
vm.push(false)
case OpNil:
vm.push(nil)
case OpNegate:
v := runtime.Negate(vm.pop())
vm.push(v)
case OpNot:
v := vm.pop().(bool)
vm.push(!v)
case OpEqual:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Equal(a, b))
case OpEqualInt:
b := vm.pop()
a := vm.pop()
vm.push(a.(int) == b.(int))
case OpEqualString:
b := vm.pop()
a := vm.pop()
vm.push(a.(string) == b.(string))
case OpJump:
vm.ip += arg
case OpJumpIfTrue:
if vm.current().(bool) {
vm.ip += arg
}
case OpJumpIfFalse:
if !vm.current().(bool) {
vm.ip += arg
}
case OpJumpIfNil:
if runtime.IsNil(vm.current()) {
vm.ip += arg
}
case OpJumpIfNotNil:
if !runtime.IsNil(vm.current()) {
vm.ip += arg
}
case OpJumpIfEnd:
scope := vm.scope()
if scope.Index >= scope.Len {
vm.ip += arg
}
case OpJumpBackward:
vm.ip -= arg
case OpIn:
b := vm.pop()
a := vm.pop()
vm.push(runtime.In(a, b))
case OpLess:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Less(a, b))
case OpMore:
b := vm.pop()
a := vm.pop()
vm.push(runtime.More(a, b))
case OpLessOrEqual:
b := vm.pop()
a := vm.pop()
vm.push(runtime.LessOrEqual(a, b))
case OpMoreOrEqual:
b := vm.pop()
a := vm.pop()
vm.push(runtime.MoreOrEqual(a, b))
case OpAdd:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Add(a, b))
case OpSubtract:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Subtract(a, b))
case OpMultiply:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Multiply(a, b))
case OpDivide:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Divide(a, b))
case OpModulo:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Modulo(a, b))
case OpExponent:
b := vm.pop()
a := vm.pop()
vm.push(runtime.Exponent(a, b))
case OpRange:
b := vm.pop()
a := vm.pop()
min := runtime.ToInt(a)
max := runtime.ToInt(b)
size := max - min + 1
if size <= 0 {
size = 0
}
vm.memGrow(uint(size))
vm.push(runtime.MakeRange(min, max))
case OpMatches:
b := vm.pop()
a := vm.pop()
if runtime.IsNil(a) || runtime.IsNil(b) {
vm.push(false)
break
}
match, err := regexp.MatchString(b.(string), a.(string))
if err != nil {
panic(err)
}
vm.push(match)
case OpMatchesConst:
a := vm.pop()
if runtime.IsNil(a) {
vm.push(false)
break
}
r := program.Constants[arg].(*regexp.Regexp)
vm.push(r.MatchString(a.(string)))
case OpContains:
b := vm.pop()
a := vm.pop()
if runtime.IsNil(a) || runtime.IsNil(b) {
vm.push(false)
break
}
vm.push(strings.Contains(a.(string), b.(string)))
case OpStartsWith:
b := vm.pop()
a := vm.pop()
if runtime.IsNil(a) || runtime.IsNil(b) {
vm.push(false)
break
}
vm.push(strings.HasPrefix(a.(string), b.(string)))
case OpEndsWith:
b := vm.pop()
a := vm.pop()
if runtime.IsNil(a) || runtime.IsNil(b) {
vm.push(false)
break
}
vm.push(strings.HasSuffix(a.(string), b.(string)))
case OpSlice:
from := vm.pop()
to := vm.pop()
node := vm.pop()
vm.push(runtime.Slice(node, from, to))
case OpCall:
fn := reflect.ValueOf(vm.pop())
size := arg
in := make([]reflect.Value, size)
for i := int(size) - 1; i >= 0; i-- {
param := vm.pop()
if param == nil {
in[i] = reflect.Zero(fn.Type().In(i))
} else {
in[i] = reflect.ValueOf(param)
}
}
out := fn.Call(in)
if len(out) == 2 && out[1].Type() == errorType && !out[1].IsNil() {
panic(out[1].Interface().(error))
}
vm.push(out[0].Interface())
case OpCall0:
out, err := program.functions[arg]()
if err != nil {
panic(err)
}
vm.push(out)
case OpCall1:
a := vm.pop()
out, err := program.functions[arg](a)
if err != nil {
panic(err)
}
vm.push(out)
case OpCall2:
b := vm.pop()
a := vm.pop()
out, err := program.functions[arg](a, b)
if err != nil {
panic(err)
}
vm.push(out)
case OpCall3:
c := vm.pop()
b := vm.pop()
a := vm.pop()
out, err := program.functions[arg](a, b, c)
if err != nil {
panic(err)
}
vm.push(out)
case OpCallN:
fn := vm.pop().(Function)
size := arg
in := make([]any, size)
for i := int(size) - 1; i >= 0; i-- {
in[i] = vm.pop()
}
out, err := fn(in...)
if err != nil {
panic(err)
}
vm.push(out)
case OpCallFast:
fn := vm.pop().(func(...any) any)
size := arg
in := make([]any, size)
for i := int(size) - 1; i >= 0; i-- {
in[i] = vm.pop()
}
vm.push(fn(in...))
case OpCallSafe:
fn := vm.pop().(SafeFunction)
size := arg
in := make([]any, size)
for i := int(size) - 1; i >= 0; i-- {
in[i] = vm.pop()
}
out, mem, err := fn(in...)
if err != nil {
panic(err)
}
vm.memGrow(mem)
vm.push(out)
case OpCallTyped:
vm.push(vm.call(vm.pop(), arg))
case OpCallBuiltin1:
vm.push(builtin.Builtins[arg].Fast(vm.pop()))
case OpArray:
size := vm.pop().(int)
vm.memGrow(uint(size))
array := make([]any, size)
for i := size - 1; i >= 0; i-- {
array[i] = vm.pop()
}
vm.push(array)
case OpMap:
size := vm.pop().(int)
vm.memGrow(uint(size))
m := make(map[string]any)
for i := size - 1; i >= 0; i-- {
value := vm.pop()
key := vm.pop()
m[key.(string)] = value
}
vm.push(m)
case OpLen:
vm.push(runtime.Len(vm.current()))
case OpCast:
switch arg {
case 0:
vm.push(runtime.ToInt(vm.pop()))
case 1:
vm.push(runtime.ToInt64(vm.pop()))
case 2:
vm.push(runtime.ToFloat64(vm.pop()))
}
case OpDeref:
a := vm.pop()
vm.push(deref.Interface(a))
case OpIncrementIndex:
vm.scope().Index++
case OpDecrementIndex:
scope := vm.scope()
scope.Index--
case OpIncrementCount:
scope := vm.scope()
scope.Count++
case OpGetIndex:
vm.push(vm.scope().Index)
case OpGetCount:
scope := vm.scope()
vm.push(scope.Count)
case OpGetLen:
scope := vm.scope()
vm.push(scope.Len)
case OpGetAcc:
vm.push(vm.scope().Acc)
case OpSetAcc:
vm.scope().Acc = vm.pop()
case OpSetIndex:
scope := vm.scope()
scope.Index = vm.pop().(int)
case OpPointer:
scope := vm.scope()
vm.push(scope.Array.Index(scope.Index).Interface())
case OpThrow:
panic(vm.pop().(error))
case OpCreate:
switch arg {
case 1:
vm.push(make(groupBy))
case 2:
scope := vm.scope()
var desc bool
switch vm.pop().(string) {
case "asc":
desc = false
case "desc":
desc = true
default:
panic("unknown order, use asc or desc")
}
vm.push(&runtime.SortBy{
Desc: desc,
Array: make([]any, 0, scope.Len),
Values: make([]any, 0, scope.Len),
})
default:
panic(fmt.Sprintf("unknown OpCreate argument %v", arg))
}
case OpGroupBy:
scope := vm.scope()
key := vm.pop()
item := scope.Array.Index(scope.Index).Interface()
scope.Acc.(groupBy)[key] = append(scope.Acc.(groupBy)[key], item)
case OpSortBy:
scope := vm.scope()
value := vm.pop()
item := scope.Array.Index(scope.Index).Interface()
sortable := scope.Acc.(*runtime.SortBy)
sortable.Array = append(sortable.Array, item)
sortable.Values = append(sortable.Values, value)
case OpSort:
scope := vm.scope()
sortable := scope.Acc.(*runtime.SortBy)
sort.Sort(sortable)
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)
vm.Scopes = append(vm.Scopes, &Scope{
Array: array,
Len: array.Len(),
})
case OpEnd:
vm.Scopes = vm.Scopes[:len(vm.Scopes)-1]
default:
panic(fmt.Sprintf("unknown bytecode %#x", op))
}
if debug && vm.debug {
vm.curr <- vm.ip
}
}
if debug && vm.debug {
close(vm.curr)
close(vm.step)
}
if len(vm.Stack) > 0 {
return vm.pop(), nil
}
return nil, nil
}
func (vm *VM) push(value any) {
vm.Stack = append(vm.Stack, value)
}
func (vm *VM) current() any {
return vm.Stack[len(vm.Stack)-1]
}
func (vm *VM) pop() any {
value := vm.Stack[len(vm.Stack)-1]
vm.Stack = vm.Stack[:len(vm.Stack)-1]
return value
}
func (vm *VM) memGrow(size uint) {
vm.memory += size
if vm.memory >= vm.MemoryBudget {
panic("memory budget exceeded")
}
}
func (vm *VM) scope() *Scope {
return vm.Scopes[len(vm.Scopes)-1]
}
func (vm *VM) Step() {
vm.step <- struct{}{}
}
func (vm *VM) Position() chan int {
return vm.curr
}