elemheap: don't reuse elements if they are still referenced
This commit is contained in:
parent
5d66898cd7
commit
1c2705dcfe
30
elemheap.go
30
elemheap.go
|
@ -7,17 +7,19 @@ requested, a row is exhausted, and the next one will
|
|||
be allocated. Previously allocated rows are tracked in
|
||||
elemHeap.rows.
|
||||
|
||||
Pos() and setPos() methods allow to query and reset the
|
||||
current position (row, and position within the row), which
|
||||
allows reusing elements. It must be made sure, that previous
|
||||
users of such storage don't access it anymore once setPos has
|
||||
been called.
|
||||
The Reset() method allows to reset the current position (row, and
|
||||
position within the row), which allows reusing elements. Whether
|
||||
elements can be reused, depends on the value of the hasGlobals
|
||||
field.
|
||||
*/
|
||||
|
||||
type elemHeap struct {
|
||||
rows [][]element
|
||||
heapPos
|
||||
rowSize int
|
||||
|
||||
base heapPos
|
||||
hasGlobals bool
|
||||
}
|
||||
|
||||
type heapPos struct {
|
||||
|
@ -38,12 +40,18 @@ func (h *elemHeap) init(size int) {
|
|||
h.rowSize = size
|
||||
h.rows = [][]element{make([]element, size)}
|
||||
h.row = h.rows[h.iRow]
|
||||
h.base = h.heapPos
|
||||
}
|
||||
|
||||
func (h *elemHeap) Pos() heapPos {
|
||||
return h.heapPos
|
||||
}
|
||||
|
||||
func (h *elemHeap) setPos(i heapPos) {
|
||||
h.heapPos = i
|
||||
func (h *elemHeap) Reset() {
|
||||
if !h.hasGlobals {
|
||||
h.heapPos = h.base
|
||||
} else {
|
||||
/* Don't restore saved position in case elements added
|
||||
* after the previous Reset call are needed in
|
||||
* global context, like notes.
|
||||
*/
|
||||
h.hasGlobals = false
|
||||
h.base = h.heapPos
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ const (
|
|||
// rebuild it using
|
||||
// make nuke
|
||||
// make parser
|
||||
needParserIfaceVersion = parserIfaceVersion_17
|
||||
needParserIfaceVersion = parserIfaceVersion_18
|
||||
)
|
||||
|
||||
// Markdown Extensions.
|
||||
|
@ -81,7 +81,7 @@ func (p *Parser) Markdown(src io.Reader, f Formatter) {
|
|||
if p.yy.extension.Notes {
|
||||
p.parseRule(ruleNotes, s)
|
||||
}
|
||||
savedPos := p.yy.state.heap.Pos()
|
||||
p.yy.state.heap.Reset()
|
||||
|
||||
for {
|
||||
tree := p.parseRule(ruleDocblock, s)
|
||||
|
@ -91,7 +91,8 @@ func (p *Parser) Markdown(src io.Reader, f Formatter) {
|
|||
s = p.yy.ResetBuffer("")
|
||||
tree = p.processRawBlocks(tree)
|
||||
f.FormatBlock(tree)
|
||||
p.yy.state.heap.setPos(savedPos)
|
||||
|
||||
p.yy.state.heap.Reset()
|
||||
}
|
||||
f.Finish()
|
||||
}
|
||||
|
|
13
parser.leg
13
parser.leg
|
@ -28,7 +28,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
parserIfaceVersion_17 = iota
|
||||
parserIfaceVersion_18 = iota
|
||||
)
|
||||
|
||||
// Semantic value of a parsing action.
|
||||
|
@ -676,7 +676,9 @@ RefTitleParens = Spnl '(' < ( !(')' Sp Newline | Newline) . )* > ')'
|
|||
|
||||
References = a:StartList
|
||||
( b:Reference { a = cons(b, a) } | SkipBlock )*
|
||||
{ p.references = reverse(a) }
|
||||
{ p.references = reverse(a)
|
||||
p.state.heap.hasGlobals = true
|
||||
}
|
||||
commit
|
||||
|
||||
Ticks1 = "`" !'`'
|
||||
|
@ -787,6 +789,7 @@ DoubleQuoted = DoubleQuoteStart
|
|||
NoteReference = &{ p.extension.Notes }
|
||||
ref:RawNoteReference
|
||||
{
|
||||
p.state.heap.hasGlobals = true
|
||||
if match, ok := p.find_note(ref.contents.str); ok {
|
||||
$$ = p.mkElem(NOTE)
|
||||
$$.children = match.children
|
||||
|
@ -814,7 +817,8 @@ InlineNote = &{ p.extension.Notes }
|
|||
( !']' Inline { a = cons($$, a) } )+
|
||||
']'
|
||||
{ $$ = p.mkList(NOTE, a)
|
||||
$$.contents.str = "" }
|
||||
p.state.heap.hasGlobals = true
|
||||
$$.contents.str = "" }
|
||||
|
||||
Notes = a:StartList
|
||||
( b:Note { a = cons(b, a) } | SkipBlock )*
|
||||
|
@ -825,7 +829,8 @@ RawNoteBlock = a:StartList
|
|||
( !BlankLine OptionallyIndentedLine { a = cons($$, a) } )+
|
||||
( < BlankLine* > { a = cons(p.mkString(yytext), a) } )
|
||||
{ $$ = p.mkStringFromList(a, true)
|
||||
$$.key = RAW
|
||||
p.state.heap.hasGlobals = true
|
||||
$$.key = RAW
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
parserIfaceVersion_17 = iota
|
||||
parserIfaceVersion_18 = iota
|
||||
)
|
||||
|
||||
// Semantic value of a parsing action.
|
||||
|
@ -1043,6 +1043,8 @@ func (p *yyParser) Init() {
|
|||
a := yyval[yyp-1]
|
||||
b := yyval[yyp-2]
|
||||
p.references = reverse(a)
|
||||
p.state.heap.hasGlobals = true
|
||||
|
||||
yyval[yyp-1] = a
|
||||
yyval[yyp-2] = b
|
||||
},
|
||||
|
@ -1121,6 +1123,7 @@ func (p *yyParser) Init() {
|
|||
func(yytext string, _ int) {
|
||||
ref := yyval[yyp-1]
|
||||
|
||||
p.state.heap.hasGlobals = true
|
||||
if match, ok := p.find_note(ref.contents.str); ok {
|
||||
yy = p.mkElem(NOTE)
|
||||
yy.children = match.children
|
||||
|
@ -1171,6 +1174,7 @@ func (p *yyParser) Init() {
|
|||
func(yytext string, _ int) {
|
||||
a := yyval[yyp-1]
|
||||
yy = p.mkList(NOTE, a)
|
||||
p.state.heap.hasGlobals = true
|
||||
yy.contents.str = ""
|
||||
yyval[yyp-1] = a
|
||||
},
|
||||
|
@ -1206,6 +1210,7 @@ func (p *yyParser) Init() {
|
|||
func(yytext string, _ int) {
|
||||
a := yyval[yyp-1]
|
||||
yy = p.mkStringFromList(a, true)
|
||||
p.state.heap.hasGlobals = true
|
||||
yy.key = RAW
|
||||
|
||||
yyval[yyp-1] = a
|
||||
|
@ -9668,7 +9673,9 @@ func (p *yyParser) Init() {
|
|||
position = position0
|
||||
return
|
||||
},
|
||||
/* 189 References <- (StartList ((Reference { a = cons(b, a) }) / SkipBlock)* { p.references = reverse(a) } commit) */
|
||||
/* 189 References <- (StartList ((Reference { a = cons(b, a) }) / SkipBlock)* { p.references = reverse(a)
|
||||
p.state.heap.hasGlobals = true
|
||||
} commit) */
|
||||
func() (match bool) {
|
||||
position0, thunkPosition0 := position, thunkPosition
|
||||
doarg(yyPush, 2)
|
||||
|
@ -12058,6 +12065,7 @@ func (p *yyParser) Init() {
|
|||
return
|
||||
},
|
||||
/* 237 NoteReference <- (&{p.extension.Notes} RawNoteReference {
|
||||
p.state.heap.hasGlobals = true
|
||||
if match, ok := p.find_note(ref.contents.str); ok {
|
||||
yy = p.mkElem(NOTE)
|
||||
yy.children = match.children
|
||||
|
@ -12188,6 +12196,7 @@ func (p *yyParser) Init() {
|
|||
return
|
||||
},
|
||||
/* 240 InlineNote <- (&{p.extension.Notes} '^[' StartList (!']' Inline { a = cons(yy, a) })+ ']' { yy = p.mkList(NOTE, a)
|
||||
p.state.heap.hasGlobals = true
|
||||
yy.contents.str = "" }) */
|
||||
func() (match bool) {
|
||||
position0, thunkPosition0 := position, thunkPosition
|
||||
|
@ -12276,8 +12285,9 @@ func (p *yyParser) Init() {
|
|||
return
|
||||
},
|
||||
/* 242 RawNoteBlock <- (StartList (!BlankLine OptionallyIndentedLine { a = cons(yy, a) })+ (< BlankLine* > { a = cons(p.mkString(yytext), a) }) { yy = p.mkStringFromList(a, true)
|
||||
yy.key = RAW
|
||||
}) */
|
||||
p.state.heap.hasGlobals = true
|
||||
yy.key = RAW
|
||||
}) */
|
||||
func() (match bool) {
|
||||
position0, thunkPosition0 := position, thunkPosition
|
||||
doarg(yyPush, 1)
|
||||
|
|
Loading…
Reference in New Issue