diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-10 21:51:57 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-10 21:51:57 +0300 |
| commit | 425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch) | |
| tree | e52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/lib/allocator | |
| parent | 90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff) | |
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/lib/allocator')
| -rw-r--r-- | vendor/libghostty-vt/src/lib/allocator/convenience.zig | 59 | ||||
| -rw-r--r-- | vendor/libghostty-vt/src/lib/allocator/wasm.zig | 98 |
2 files changed, 98 insertions, 59 deletions
diff --git a/vendor/libghostty-vt/src/lib/allocator/convenience.zig b/vendor/libghostty-vt/src/lib/allocator/convenience.zig deleted file mode 100644 index 0f5f88d2..00000000 --- a/vendor/libghostty-vt/src/lib/allocator/convenience.zig +++ /dev/null @@ -1,59 +0,0 @@ -//! This contains convenience functions for allocating various types. -//! -//! The primary use case for this is Wasm builds. Ghostty relies a lot on -//! pointers to various types for ABI compatibility and creating those pointers -//! in Wasm is tedious. This file contains a purely additive set of functions -//! that can be exposed to the Wasm module without changing the API from the -//! C library. -//! -//! Given these are convenience methods, they always use the default allocator. -//! If a caller is using a custom allocator, they have the expertise to -//! allocate these types manually using their custom allocator. - -// Get our default allocator at comptime since it is known. -const default = @import("../allocator.zig").default; -const alloc = default(null); - -pub const Opaque = *anyopaque; - -pub fn allocOpaque() callconv(.c) ?*Opaque { - return alloc.create(*anyopaque) catch return null; -} - -pub fn freeOpaque(ptr: ?*Opaque) callconv(.c) void { - if (ptr) |p| alloc.destroy(p); -} - -pub fn allocU8Array(len: usize) callconv(.c) ?[*]u8 { - const slice = alloc.alloc(u8, len) catch return null; - return slice.ptr; -} - -pub fn freeU8Array(ptr: ?[*]u8, len: usize) callconv(.c) void { - if (ptr) |p| alloc.free(p[0..len]); -} - -pub fn allocU16Array(len: usize) callconv(.c) ?[*]u16 { - const slice = alloc.alloc(u16, len) catch return null; - return slice.ptr; -} - -pub fn freeU16Array(ptr: ?[*]u16, len: usize) callconv(.c) void { - if (ptr) |p| alloc.free(p[0..len]); -} - -pub fn allocU8() callconv(.c) ?*u8 { - return alloc.create(u8) catch return null; -} - -pub fn freeU8(ptr: ?*u8) callconv(.c) void { - if (ptr) |p| alloc.destroy(p); -} - -pub fn allocUsize() callconv(.c) ?*usize { - return alloc.create(usize) catch return null; -} - -pub fn freeUsize(ptr: ?*usize) callconv(.c) void { - if (ptr) |p| alloc.destroy(p); -} diff --git a/vendor/libghostty-vt/src/lib/allocator/wasm.zig b/vendor/libghostty-vt/src/lib/allocator/wasm.zig new file mode 100644 index 00000000..22439103 --- /dev/null +++ b/vendor/libghostty-vt/src/lib/allocator/wasm.zig @@ -0,0 +1,98 @@ +//! Wasm allocation conveniences for caller-owned storage and opaque out slots. +//! +//! The primary use case for this is Wasm builds. Ghostty relies a lot on +//! pointers to various types for ABI compatibility and creating those pointers +//! in Wasm is tedious. This file contains the small set of functions exposed by +//! the Wasm module without changing the API from the C library. +//! +//! Given these are convenience methods, they always use the default allocator. +//! If a caller is using a custom allocator, they have the expertise to +//! allocate these types manually using their custom allocator. + +const std = @import("std"); +const c_abi = @import("../c_abi.zig"); + +// Get our default allocator at comptime since it is known. +const default = @import("../allocator.zig").default; +const alloc = default(null); +const wasm_alignment: std.mem.Alignment = .fromByteUnits(c_abi.max_alignment); + +/// A nullable opaque C handle stored in a constructor out-parameter slot. +pub const Opaque = ?*anyopaque; + +/// Allocate `len` bytes of uninitialized, caller-owned Wasm ABI storage. +/// +/// The returned pointer is aligned for any fundamental C ABI type and must be +/// released with `freeBytes` using the same `len`. Returns null when `len` is +/// zero or allocation fails. +pub fn allocBytes(len: usize) callconv(.c) ?[*]u8 { + if (len == 0) return null; + return alloc.rawAlloc(len, wasm_alignment, @returnAddress()); +} + +/// Release storage returned by `allocBytes`. +/// +/// `len` must exactly match the allocation length. A null pointer is ignored. +pub fn freeBytes(ptr: ?[*]u8, len: usize) callconv(.c) void { + const p = ptr orelse return; + if (len == 0) return; + alloc.rawFree(p[0..len], wasm_alignment, @returnAddress()); +} + +/// Allocate a null-initialized slot for an opaque constructor out-parameter. +/// +/// The slot may be reused after each value is removed with `takeOpaque`. It +/// must eventually be released with `freeOpaque`. +pub fn allocOpaque() callconv(.c) ?*Opaque { + const ptr = allocBytes(@sizeOf(Opaque)) orelse return null; + const result: *Opaque = @ptrCast(@alignCast(ptr)); + result.* = null; + return result; +} + +/// Release a slot returned by `allocOpaque` without freeing its stored handle. +/// +/// Call the handle's type-specific destructor before freeing a populated slot. +/// A null slot pointer is ignored. +pub fn freeOpaque(ptr: ?*Opaque) callconv(.c) void { + freeBytes(@ptrCast(ptr), @sizeOf(Opaque)); +} + +/// Remove and return the handle in an opaque out-parameter slot. +/// +/// The slot is reset to null so it can be safely reused for another +/// constructor. This does not free either the handle or the slot. Returns null +/// when the slot pointer is null or the slot is empty. +pub fn takeOpaque(ptr: ?*Opaque) callconv(.c) Opaque { + const p = ptr orelse return null; + const result = p.*; + p.* = null; + return result; +} + +test "Wasm allocation" { + const ptr = allocBytes(1) orelse return error.OutOfMemory; + defer freeBytes(ptr, 1); + + try std.testing.expectEqual( + @as(usize, 0), + @intFromPtr(ptr) % c_abi.max_alignment, + ); + ptr[0] = 42; + try std.testing.expectEqual(@as(u8, 42), ptr[0]); + + try std.testing.expect(allocBytes(0) == null); + freeBytes(null, 0); +} + +test "opaque slots are initialized and reusable" { + const slot = allocOpaque() orelse return error.OutOfMemory; + defer freeOpaque(slot); + + try std.testing.expect(takeOpaque(slot) == null); + + var value: u8 = 42; + slot.* = &value; + try std.testing.expectEqual(@as(?*anyopaque, &value), takeOpaque(slot)); + try std.testing.expect(takeOpaque(slot) == null); +} |
