perf: Fixed leaks in commonmark code.

This commit is contained in:
Spencer Brower
2026-08-02 16:20:54 -04:00
parent 4c41d85385
commit 806c153979
4 changed files with 23 additions and 9 deletions
+2 -1
View File
@@ -194,7 +194,8 @@ main :: proc () {
- [x] basic poll loop - [x] basic poll loop
- [ ] filesystem poll loop - [ ] filesystem poll loop
- [ ] event based - [ ] event based
- [ ] Free cmark HTML output (`body_html`) — cmark allocates via C malloc, not the arena, so it leaks per iteration in watch mode - [x] Free cmark HTML output (`body_html`) — cmark allocates via C malloc, not the arena, so it leaks per iteration in watch mode
- [ ] manually pass `site_allocator` to `load_page`
- [ ] Mount content in VFS - [ ] Mount content in VFS
- [ ] commands - [ ] commands
- [ ] `build` alias of default - [ ] `build` alias of default
+4 -3
View File
@@ -3,9 +3,9 @@ package main
import md "markdown" import md "markdown"
import ts "treesitter" import ts "treesitter"
import "core:encoding/json"
import "core:fmt" import "core:fmt"
import "core:log" import "core:log"
import "core:encoding/json"
import "core:os" import "core:os"
import "core:strings" import "core:strings"
import "core:time" import "core:time"
@@ -275,9 +275,9 @@ load_page :: proc(
page.og = fm.og page.og = fm.og
if strings.has_suffix(file_path, ".html") { if strings.has_suffix(file_path, ".html") {
page.content = strings.clone(body) page.content = strings.clone(body, context.allocator)
} else { } else {
page.content = md.process(body, ext, file_path) page.content = md.process(body, ext, file_path, context.allocator)
} }
ok = true ok = true
@@ -295,3 +295,4 @@ strip_extension :: proc(name: string) -> string {
} }
return name[:dot] return name[:dot]
} }
+4 -2
View File
@@ -171,8 +171,9 @@ inject_notes :: proc(html: string, sn_defs, mn_defs: map[string]string) -> strin
} }
// Render definition through cmark for markdown support // Render definition through cmark for markdown support
def_html := cm.markdown_to_html_from_string(def_text, {.Unsafe}) raw_html := cm.markdown_to_html_from_string(def_text, {.Unsafe})
def_html = strip_p_tags(def_html) defer cm.free_string(raw_html)
def_html := strip_p_tags(raw_html)
note: string note: string
defer delete(note) defer delete(note)
@@ -210,3 +211,4 @@ strip_p_tags :: proc(html: string) -> string {
} }
return s return s
} }
+12 -2
View File
@@ -16,14 +16,23 @@ Extension :: enum {
DEFAULT_EXTENSIONS :: bit_set[Extension]{.Emoji, .Sidenotes, .Alerts, .HeadingIDs} DEFAULT_EXTENSIONS :: bit_set[Extension]{.Emoji, .Sidenotes, .Alerts, .HeadingIDs}
process :: proc(body: string, ext: bit_set[Extension], file_path: string) -> string { // Caller is responsible for freeing string
process :: proc(
body: string,
ext: bit_set[Extension],
file_path: string,
allocator := context.allocator,
) -> string {
side_notes := make(map[string]string) side_notes := make(map[string]string)
margin_notes := make(map[string]string) margin_notes := make(map[string]string)
clean_body := body clean_body := body
if .Sidenotes in ext { if .Sidenotes in ext {
clean_body, side_notes, margin_notes = strip_definitions(body) clean_body, side_notes, margin_notes = strip_definitions(body)
} }
html := cm.markdown_to_html_from_string(clean_body, {.Unsafe}) original_html := cm.markdown_to_html_from_string(clean_body, {.Unsafe})
html := strings.clone(original_html, allocator)
cm.free_string(original_html)
if .Emoji in ext { if .Emoji in ext {
html = expand_emoji(html) html = expand_emoji(html)
} }
@@ -88,3 +97,4 @@ apply_extension_config :: proc(ext: ^bit_set[Extension], config: json.Object) {
} }
} }
} }