stack_tags_js.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // +build js
  2. package gls
  3. // This file is used for GopherJS builds, which don't have normal runtime support
  4. import (
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. "github.com/gopherjs/gopherjs/js"
  9. )
  10. var stackRE = regexp.MustCompile("\\s+at (\\S*) \\([^:]+:(\\d+):(\\d+)")
  11. func findPtr() uintptr {
  12. jsStack := js.Global.Get("Error").New().Get("stack").Call("split", "\n")
  13. for i := 1; i < jsStack.Get("length").Int(); i++ {
  14. item := jsStack.Index(i).String()
  15. matches := stackRE.FindAllStringSubmatch(item, -1)
  16. if matches == nil {
  17. return 0
  18. }
  19. pkgPath := matches[0][1]
  20. if strings.HasPrefix(pkgPath, "$packages.github.com/jtolds/gls.mark") {
  21. line, _ := strconv.Atoi(matches[0][2])
  22. char, _ := strconv.Atoi(matches[0][3])
  23. x := (uintptr(line) << 16) | uintptr(char)
  24. return x
  25. }
  26. }
  27. return 0
  28. }
  29. func init() {
  30. setEntries := func(f func(uint, func()), v int8) {
  31. var ptr uintptr
  32. f(0, func() {
  33. ptr = findPtr()
  34. })
  35. pc_lookup[ptr] = v
  36. if v >= 0 {
  37. mark_lookup[v] = f
  38. }
  39. }
  40. setEntries(markS, -0x1)
  41. setEntries(mark0, 0x0)
  42. setEntries(mark1, 0x1)
  43. setEntries(mark2, 0x2)
  44. setEntries(mark3, 0x3)
  45. setEntries(mark4, 0x4)
  46. setEntries(mark5, 0x5)
  47. setEntries(mark6, 0x6)
  48. setEntries(mark7, 0x7)
  49. setEntries(mark8, 0x8)
  50. setEntries(mark9, 0x9)
  51. setEntries(markA, 0xa)
  52. setEntries(markB, 0xb)
  53. setEntries(markC, 0xc)
  54. setEntries(markD, 0xd)
  55. setEntries(markE, 0xe)
  56. setEntries(markF, 0xf)
  57. }
  58. func currentStack(skip int) (stack []uintptr) {
  59. jsStack := js.Global.Get("Error").New().Get("stack").Call("split", "\n")
  60. for i := skip + 2; i < jsStack.Get("length").Int(); i++ {
  61. item := jsStack.Index(i).String()
  62. matches := stackRE.FindAllStringSubmatch(item, -1)
  63. if matches == nil {
  64. return stack
  65. }
  66. line, _ := strconv.Atoi(matches[0][2])
  67. char, _ := strconv.Atoi(matches[0][3])
  68. x := (uintptr(line) << 16) | uintptr(char)&0xffff
  69. stack = append(stack, x)
  70. }
  71. return stack
  72. }
  73. func readStackTags(skip int) (tags []uint) {
  74. stack := currentStack(skip)
  75. var current_tag uint
  76. for _, pc := range stack {
  77. val, ok := pc_lookup[pc]
  78. if !ok {
  79. continue
  80. }
  81. if val < 0 {
  82. tags = append(tags, current_tag)
  83. current_tag = 0
  84. continue
  85. }
  86. current_tag <<= bitWidth
  87. current_tag += uint(val)
  88. }
  89. return
  90. }