diff options
author | qrort <[email protected]> | 2022-11-30 23:47:12 +0300 |
---|---|---|
committer | qrort <[email protected]> | 2022-11-30 23:47:12 +0300 |
commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /library/go/x | |
parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) |
validate canons without yatest_common
Diffstat (limited to 'library/go/x')
-rw-r--r-- | library/go/x/xreflect/assign.go | 17 | ||||
-rw-r--r-- | library/go/x/xruntime/stacktrace.go | 69 |
2 files changed, 86 insertions, 0 deletions
diff --git a/library/go/x/xreflect/assign.go b/library/go/x/xreflect/assign.go new file mode 100644 index 00000000000..624612575c8 --- /dev/null +++ b/library/go/x/xreflect/assign.go @@ -0,0 +1,17 @@ +package xreflect + +import "reflect" + +// Assign source's value to target's value it points to. Source must be value, target must be pointer to existing value. +// Source must be assignable to target's value it points to. +func Assign(source interface{}, target interface{}) bool { + val := reflect.ValueOf(target) + typ := val.Type() + targetType := typ.Elem() + if reflect.TypeOf(source).AssignableTo(targetType) { + val.Elem().Set(reflect.ValueOf(source)) + return true + } + + return false +} diff --git a/library/go/x/xruntime/stacktrace.go b/library/go/x/xruntime/stacktrace.go new file mode 100644 index 00000000000..5c5e661188f --- /dev/null +++ b/library/go/x/xruntime/stacktrace.go @@ -0,0 +1,69 @@ +package xruntime + +import ( + "runtime" +) + +type StackTrace struct { + frames []uintptr + full bool +} + +func NewStackTrace16(skip int) *StackTrace { + var pcs [16]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func NewStackTrace32(skip int) *StackTrace { + var pcs [32]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func NewStackTrace64(skip int) *StackTrace { + var pcs [64]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func NewStackTrace128(skip int) *StackTrace { + var pcs [128]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func newStackTrace(skip int, pcs []uintptr) *StackTrace { + n := runtime.Callers(skip+1, pcs) + return &StackTrace{frames: pcs[:n], full: true} +} + +func NewFrame(skip int) *StackTrace { + var pcs [3]uintptr + n := runtime.Callers(skip+1, pcs[:]) + return &StackTrace{frames: pcs[:n]} +} + +func (st *StackTrace) Frames() []runtime.Frame { + frames := runtime.CallersFrames(st.frames[:]) + if !st.full { + if _, ok := frames.Next(); !ok { + return nil + } + + fr, ok := frames.Next() + if !ok { + return nil + } + + return []runtime.Frame{fr} + } + + var res []runtime.Frame + for { + frame, more := frames.Next() + if !more { + break + } + + res = append(res, frame) + } + + return res +} |