1// +build js 2 3package gls 4 5// This file is used for GopherJS builds, which don't have normal runtime 6// stack trace support 7 8import ( 9 "strconv" 10 "strings" 11 12 "github.com/gopherjs/gopherjs/js" 13) 14 15const ( 16 jsFuncNamePrefix = "github_com_jtolds_gls_mark" 17) 18 19func jsMarkStack() (f []uintptr) { 20 lines := strings.Split( 21 js.Global.Get("Error").New().Get("stack").String(), "\n") 22 f = make([]uintptr, 0, len(lines)) 23 for i, line := range lines { 24 line = strings.TrimSpace(line) 25 if line == "" { 26 continue 27 } 28 if i == 0 { 29 if line != "Error" { 30 panic("didn't understand js stack trace") 31 } 32 continue 33 } 34 fields := strings.Fields(line) 35 if len(fields) < 2 || fields[0] != "at" { 36 panic("didn't understand js stack trace") 37 } 38 39 pos := strings.Index(fields[1], jsFuncNamePrefix) 40 if pos < 0 { 41 continue 42 } 43 pos += len(jsFuncNamePrefix) 44 if pos >= len(fields[1]) { 45 panic("didn't understand js stack trace") 46 } 47 char := string(fields[1][pos]) 48 switch char { 49 case "S": 50 f = append(f, uintptr(0)) 51 default: 52 val, err := strconv.ParseUint(char, 16, 8) 53 if err != nil { 54 panic("didn't understand js stack trace") 55 } 56 f = append(f, uintptr(val)+1) 57 } 58 } 59 return f 60} 61 62// variables to prevent inlining 63var ( 64 findPtr = func() uintptr { 65 funcs := jsMarkStack() 66 if len(funcs) == 0 { 67 panic("failed to find function pointer") 68 } 69 return funcs[0] 70 } 71 72 getStack = func(offset, amount int) (stack []uintptr, next_offset int) { 73 return jsMarkStack(), 0 74 } 75) 76