summaryrefslogtreecommitdiff
path: root/src/syntax.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax.zig')
-rw-r--r--src/syntax.zig69
1 files changed, 5 insertions, 64 deletions
diff --git a/src/syntax.zig b/src/syntax.zig
index e637bf67..5c8b9c0f 100644
--- a/src/syntax.zig
+++ b/src/syntax.zig
@@ -3,6 +3,7 @@ const config = @import("pardes_config");
const tracy = @import("tracy.zig");
const grammar_manifest = @import("grammar_manifest.zig");
const look = @import("look.zig");
+const c_heap = @import("c_heap");
pub const enabled = config.syntax_highlighting;
const zig_grammar = config.syntax_zig_grammar;
@@ -139,8 +140,10 @@ fn initSpecs() [specCount()]Spec {
var specs = initSpecs();
-const allocation_header_size = 16;
+/// What the tree-sitter runtime allocates from: `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;
extern fn ts_set_allocator(
@@ -150,56 +153,13 @@ extern fn ts_set_allocator(
new_free: ?*const fn (ptr: ?*anyopaque) callconv(.c) void,
) void;
-fn syntaxAlloc(size_arg: usize) callconv(.c) ?*anyopaque {
- const size = @max(size_arg, 1);
- const total = std.math.add(usize, allocation_header_size, size) catch return null;
- const bytes = syntax_allocator.alignedAlloc(u8, .@"16", total) catch return null;
- const header: *align(16) usize = @ptrCast(bytes.ptr);
- header.* = total;
- return @ptrCast(bytes.ptr + allocation_header_size);
-}
-
-fn syntaxCalloc(count: usize, size: usize) callconv(.c) ?*anyopaque {
- const len = std.math.mul(usize, count, size) catch return null;
- const pointer = syntaxAlloc(len) orelse return null;
- const bytes: [*]u8 = @ptrCast(pointer);
- @memset(bytes[0..len], 0);
- return pointer;
-}
-
-fn syntaxRealloc(ptr: ?*anyopaque, new_size: usize) callconv(.c) ?*anyopaque {
- const pointer = ptr orelse return syntaxAlloc(new_size);
- if (new_size == 0) {
- syntaxFree(pointer);
- return null;
- }
- const user: [*]u8 = @ptrCast(pointer);
- const header: *align(16) usize = @ptrCast(@alignCast(user - allocation_header_size));
- const old_total = header.*;
- const old_bytes: []align(16) u8 = @as([*]align(16) u8, @ptrCast(header))[0..old_total];
- const new_total = std.math.add(usize, allocation_header_size, new_size) catch return null;
- const new_bytes = syntax_allocator.realloc(old_bytes, new_total) catch return null;
- const new_header: *align(16) usize = @ptrCast(new_bytes.ptr);
- new_header.* = new_total;
- return @ptrCast(new_bytes.ptr + allocation_header_size);
-}
-
-fn syntaxFree(ptr: ?*anyopaque) callconv(.c) void {
- const pointer = ptr orelse return;
- const user: [*]u8 = @ptrCast(pointer);
- const header: *align(16) usize = @ptrCast(@alignCast(user - allocation_header_size));
- const total = header.*;
- const bytes: []align(16) u8 = @as([*]align(16) u8, @ptrCast(header))[0..total];
- syntax_allocator.free(bytes);
-}
-
pub fn start(gpa: std.mem.Allocator) void {
if (comptime enabled) {
std.debug.assert(!syntax_started);
stop();
syntax_allocator = gpa;
syntax_started = true;
- ts_set_allocator(syntaxAlloc, syntaxCalloc, syntaxRealloc, syntaxFree);
+ ts_set_allocator(syntax_heap.malloc, syntax_heap.calloc, syntax_heap.realloc, syntax_heap.free);
}
}
@@ -935,25 +895,6 @@ test "syntax codeAfterLocation takes whole-token locations and nothing else" {
try std.testing.expect(codeAfterLocation(" leading space") == null);
}
-test "syntax tree-sitter allocator callbacks preserve and free exact allocations" {
- syntax_allocator = std.testing.allocator;
- defer syntax_allocator = undefined;
-
- var live: ?*anyopaque = syntaxCalloc(4, 1) orelse return error.OutOfMemory;
- defer if (live) |pointer| syntaxFree(pointer);
- const original: [*]u8 = @ptrCast(live.?);
- try std.testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0 }, original[0..4]);
- @memcpy(original[0..4], "data");
-
- live = syntaxRealloc(live, 32) orelse return error.OutOfMemory;
- const grown: [*]u8 = @ptrCast(live.?);
- try std.testing.expectEqualSlices(u8, "data", grown[0..4]);
-
- try std.testing.expect(syntaxCalloc(std.math.maxInt(usize), 2) == null);
- try std.testing.expect(syntaxRealloc(live, 0) == null);
- live = null;
-}
-
test "syntax default full grammar set highlights Typst source" {
if (!enabled or !full_grammars) return;
start(std.testing.allocator);