summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/syntax.zig5
-rw-r--r--src/tree_sitter_heap.h27
2 files changed, 30 insertions, 2 deletions
diff --git a/src/syntax.zig b/src/syntax.zig
index 5c8b9c0f..9c1a4f4b 100644
--- a/src/syntax.zig
+++ b/src/syntax.zig
@@ -140,8 +140,9 @@ fn initSpecs() [specCount()]Spec {
var specs = initSpecs();
-/// What the tree-sitter runtime allocates from: `start`'s allocator, through
-/// the shared C heap.
+/// What tree-sitter allocates from, the runtime and every grammar's external
+/// scanner (build.zig compiles them to use the runtime's allocator):
+/// `start`'s allocator, through the shared C heap.
var syntax_allocator: std.mem.Allocator = undefined;
const syntax_heap = c_heap.Heap(&syntax_allocator);
var syntax_started = false;
diff --git a/src/tree_sitter_heap.h b/src/tree_sitter_heap.h
new file mode 100644
index 00000000..66083be8
--- /dev/null
+++ b/src/tree_sitter_heap.h
@@ -0,0 +1,27 @@
+/* Forced into every tree-sitter grammar build ahead of its own source
+ * (build.zig passes -include). A few external scanners (bash, markdown,
+ * markdown_inline, python, typst) call malloc, calloc, realloc and free
+ * themselves rather than tree-sitter's ts_malloc and friends, so they would
+ * allocate from libc behind the Zig allocator syntax.zig hands the runtime.
+ * stdlib.h comes first so its declarations are made with the real names;
+ * from here on the four names are the runtime's current allocator functions,
+ * the ones ts_set_allocator sets. The scanners that do use ts_malloc get the
+ * same through tree_sitter/alloc.h and TREE_SITTER_REUSE_ALLOCATOR. A scanner
+ * frees only what it allocated itself, so none of this memory crosses into
+ * the runtime or out of it. */
+#ifndef PARDES_TREE_SITTER_HEAP_H
+#define PARDES_TREE_SITTER_HEAP_H
+
+#include <stdlib.h>
+
+extern void *(*ts_current_malloc)(size_t size);
+extern void *(*ts_current_calloc)(size_t count, size_t size);
+extern void *(*ts_current_realloc)(void *ptr, size_t size);
+extern void (*ts_current_free)(void *ptr);
+
+#define malloc(size) ts_current_malloc(size)
+#define calloc(count, size) ts_current_calloc(count, size)
+#define realloc(ptr, size) ts_current_realloc(ptr, size)
+#define free(ptr) ts_current_free(ptr)
+
+#endif