summaryrefslogtreecommitdiffstats
path: root/library/go/x
diff options
context:
space:
mode:
authorqrort <[email protected]>2022-11-30 23:47:12 +0300
committerqrort <[email protected]>2022-11-30 23:47:12 +0300
commit22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch)
treebffa27765faf54126ad44bcafa89fadecb7a73d7 /library/go/x
parent332b99e2173f0425444abb759eebcb2fafaa9209 (diff)
validate canons without yatest_common
Diffstat (limited to 'library/go/x')
-rw-r--r--library/go/x/xreflect/assign.go17
-rw-r--r--library/go/x/xruntime/stacktrace.go69
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
+}