1
2
3
4
5 package dwarfgen
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/internal/src"
11 )
12
13
14
15 type ScopeMarker struct {
16 parents []ir.ScopeID
17 marks []ir.Mark
18 }
19
20
21 func (m *ScopeMarker) checkPos(pos src.XPos) ir.ScopeID {
22 if !pos.IsKnown() {
23 base.Fatalf("unknown scope position")
24 }
25
26 if len(m.marks) == 0 {
27 return 0
28 }
29
30 last := &m.marks[len(m.marks)-1]
31 if xposBefore(pos, last.Pos) {
32 base.FatalfAt(pos, "non-monotonic scope positions\n\t%v: previous scope position", base.FmtPos(last.Pos))
33 }
34 return last.Scope
35 }
36
37
38 func (m *ScopeMarker) Push(pos src.XPos) {
39 current := m.checkPos(pos)
40
41 m.parents = append(m.parents, current)
42 child := ir.ScopeID(len(m.parents))
43
44 m.marks = append(m.marks, ir.Mark{Pos: pos, Scope: child})
45 }
46
47
48 func (m *ScopeMarker) Pop(pos src.XPos) {
49 current := m.checkPos(pos)
50
51 parent := m.parents[current-1]
52
53 m.marks = append(m.marks, ir.Mark{Pos: pos, Scope: parent})
54 }
55
56
57 func (m *ScopeMarker) Unpush() {
58 i := len(m.marks) - 1
59 current := m.marks[i].Scope
60
61 if current != ir.ScopeID(len(m.parents)) {
62 base.FatalfAt(m.marks[i].Pos, "current scope is not empty")
63 }
64
65 m.parents = m.parents[:current-1]
66 m.marks = m.marks[:i]
67 }
68
69
70
71 func (m *ScopeMarker) WriteTo(fn *ir.Func) {
72 m.compactMarks()
73
74 fn.Parents = make([]ir.ScopeID, len(m.parents))
75 copy(fn.Parents, m.parents)
76 m.parents = m.parents[:0]
77
78 fn.Marks = make([]ir.Mark, len(m.marks))
79 copy(fn.Marks, m.marks)
80 m.marks = m.marks[:0]
81 }
82
83 func (m *ScopeMarker) compactMarks() {
84 n := 0
85 for _, next := range m.marks {
86 if n > 0 && next.Pos == m.marks[n-1].Pos {
87 m.marks[n-1].Scope = next.Scope
88 continue
89 }
90 m.marks[n] = next
91 n++
92 }
93 m.marks = m.marks[:n]
94 }
95
View as plain text