mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-16 00:08:59 +00:00
fix freeing with new combined chains
This commit is contained in:
@@ -40,6 +40,13 @@ const Factory = @This();
|
|||||||
_page: *Page,
|
_page: *Page,
|
||||||
_slab: SlabAllocator,
|
_slab: SlabAllocator,
|
||||||
|
|
||||||
|
pub const FactoryAllocationKind = union(enum) {
|
||||||
|
/// Allocated as part of a Factory PrototypeChain
|
||||||
|
chain: []u8,
|
||||||
|
/// Allocated standalone via factory.create()
|
||||||
|
standalone,
|
||||||
|
};
|
||||||
|
|
||||||
fn PrototypeChain(comptime types: []const type) type {
|
fn PrototypeChain(comptime types: []const type) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
@@ -96,7 +103,7 @@ fn PrototypeChain(comptime types: []const type) type {
|
|||||||
|
|
||||||
fn setRoot(self: *const Self, comptime T: type) void {
|
fn setRoot(self: *const Self, comptime T: type) void {
|
||||||
const ptr = self.get(0);
|
const ptr = self.get(0);
|
||||||
ptr.* = .{ ._type = unionInit(T, self.get(1)) };
|
ptr.* = .{ ._type = unionInit(T, self.get(1)), ._allocation = FactoryAllocationKind{ .chain = self.memory } };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setMiddle(self: *const Self, comptime index: usize, comptime T: type) void {
|
fn setMiddle(self: *const Self, comptime index: usize, comptime T: type) void {
|
||||||
@@ -163,6 +170,46 @@ pub fn eventTarget(self: *Factory, child: anytype) !*@TypeOf(child) {
|
|||||||
return chain.get(1);
|
return chain.get(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is a root object
|
||||||
|
pub fn event(self: *Factory, typ: []const u8, child: anytype) !*@TypeOf(child) {
|
||||||
|
const allocator = self._slab.allocator();
|
||||||
|
|
||||||
|
// Special case: Event has a _type_string field, so we need manual setup
|
||||||
|
const chain = try PrototypeChain(
|
||||||
|
&.{ Event, @TypeOf(child) },
|
||||||
|
).allocate(allocator);
|
||||||
|
|
||||||
|
const event_ptr = chain.get(0);
|
||||||
|
event_ptr.* = .{
|
||||||
|
._type = unionInit(Event.Type, chain.get(1)),
|
||||||
|
._type_string = try String.init(self._page.arena, typ, .{}),
|
||||||
|
._allocation = FactoryAllocationKind{ .chain = chain.memory },
|
||||||
|
};
|
||||||
|
chain.setLeaf(1, child);
|
||||||
|
|
||||||
|
return chain.get(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blob(self: *Factory, child: anytype) !*@TypeOf(child) {
|
||||||
|
const allocator = self._slab.allocator();
|
||||||
|
|
||||||
|
// Special case: Blob has slice and mime fields, so we need manual setup
|
||||||
|
const chain = try PrototypeChain(
|
||||||
|
&.{ Blob, @TypeOf(child) },
|
||||||
|
).allocate(allocator);
|
||||||
|
|
||||||
|
const blob_ptr = chain.get(0);
|
||||||
|
blob_ptr.* = .{
|
||||||
|
._type = unionInit(Blob.Type, chain.get(1)),
|
||||||
|
._allocation = FactoryAllocationKind{ .chain = chain.memory },
|
||||||
|
.slice = "",
|
||||||
|
.mime = "",
|
||||||
|
};
|
||||||
|
chain.setLeaf(1, child);
|
||||||
|
|
||||||
|
return chain.get(1);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn node(self: *Factory, child: anytype) !*@TypeOf(child) {
|
pub fn node(self: *Factory, child: anytype) !*@TypeOf(child) {
|
||||||
const allocator = self._slab.allocator();
|
const allocator = self._slab.allocator();
|
||||||
return try AutoPrototypeChain(
|
return try AutoPrototypeChain(
|
||||||
@@ -223,25 +270,6 @@ pub fn svgElement(self: *Factory, tag_name: []const u8, child: anytype) !*@TypeO
|
|||||||
return chain.get(4);
|
return chain.get(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a root object
|
|
||||||
pub fn event(self: *Factory, typ: []const u8, child: anytype) !*@TypeOf(child) {
|
|
||||||
const allocator = self._slab.allocator();
|
|
||||||
|
|
||||||
// Special case: Event has a _type_string field, so we need manual setup
|
|
||||||
const chain = try PrototypeChain(
|
|
||||||
&.{ Event, @TypeOf(child) },
|
|
||||||
).allocate(allocator);
|
|
||||||
|
|
||||||
const event_ptr = chain.get(0);
|
|
||||||
event_ptr.* = .{
|
|
||||||
._type = unionInit(Event.Type, chain.get(1)),
|
|
||||||
._type_string = try String.init(self._page.arena, typ, .{}),
|
|
||||||
};
|
|
||||||
chain.setLeaf(1, child);
|
|
||||||
|
|
||||||
return chain.get(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn xhrEventTarget(self: *Factory, child: anytype) !*@TypeOf(child) {
|
pub fn xhrEventTarget(self: *Factory, child: anytype) !*@TypeOf(child) {
|
||||||
const allocator = self._slab.allocator();
|
const allocator = self._slab.allocator();
|
||||||
|
|
||||||
@@ -250,28 +278,9 @@ pub fn xhrEventTarget(self: *Factory, child: anytype) !*@TypeOf(child) {
|
|||||||
).create(allocator, child);
|
).create(allocator, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blob(self: *Factory, child: anytype) !*@TypeOf(child) {
|
|
||||||
const allocator = self._slab.allocator();
|
|
||||||
|
|
||||||
// Special case: Blob has slice and mime fields, so we need manual setup
|
|
||||||
const chain = try PrototypeChain(
|
|
||||||
&.{ Blob, @TypeOf(child) },
|
|
||||||
).allocate(allocator);
|
|
||||||
|
|
||||||
const blob_ptr = chain.get(0);
|
|
||||||
blob_ptr.* = .{
|
|
||||||
._type = unionInit(Blob.Type, chain.get(1)),
|
|
||||||
.slice = "",
|
|
||||||
.mime = "",
|
|
||||||
};
|
|
||||||
chain.setLeaf(1, child);
|
|
||||||
|
|
||||||
return chain.get(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroy(self: *Factory, value: anytype) void {
|
pub fn destroy(self: *Factory, value: anytype) void {
|
||||||
const S = reflect.Struct(@TypeOf(value));
|
const S = reflect.Struct(@TypeOf(value));
|
||||||
// const allocator = self._slab.allocator();
|
const allocator = self._slab.allocator();
|
||||||
|
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
// We should always destroy from the leaf down.
|
// We should always destroy from the leaf down.
|
||||||
@@ -286,12 +295,14 @@ pub fn destroy(self: *Factory, value: anytype) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const root_ptr = self.destroyChain(value, true);
|
const allocation_kind = self.destroyChain(value, true) orelse return;
|
||||||
_ = root_ptr;
|
switch (allocation_kind) {
|
||||||
// allocator.destroy(root_ptr);
|
.chain => |buf| allocator.free(buf),
|
||||||
|
.standalone => {},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroyChain(self: *Factory, value: anytype, comptime first: bool) *@TypeOf(value) {
|
fn destroyChain(self: *Factory, value: anytype, comptime first: bool) ?FactoryAllocationKind {
|
||||||
const S = reflect.Struct(@TypeOf(value));
|
const S = reflect.Struct(@TypeOf(value));
|
||||||
const allocator = self._slab.allocator();
|
const allocator = self._slab.allocator();
|
||||||
|
|
||||||
@@ -317,9 +328,9 @@ fn destroyChain(self: *Factory, value: anytype, comptime first: bool) *@TypeOf(v
|
|||||||
if (self._page.js.removeTaggedMapping(@intFromPtr(value))) |tagged| {
|
if (self._page.js.removeTaggedMapping(@intFromPtr(value))) |tagged| {
|
||||||
allocator.destroy(tagged);
|
allocator.destroy(tagged);
|
||||||
}
|
}
|
||||||
}
|
} else if (@hasField(S, "_allocation")) {
|
||||||
|
return value._allocation;
|
||||||
return @ptrCast(value);
|
} else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createT(self: *Factory, comptime T: type) !*T {
|
pub fn createT(self: *Factory, comptime T: type) !*T {
|
||||||
|
|||||||
@@ -176,8 +176,8 @@ pub fn deinit(self: *Page) void {
|
|||||||
log.debug(.page, "page.deinit", .{ .url = self.url });
|
log.debug(.page, "page.deinit", .{ .url = self.url });
|
||||||
|
|
||||||
// Uncomment if you want slab statistics to print.
|
// Uncomment if you want slab statistics to print.
|
||||||
// const stats = self._factory._slab.getStats(self.arena) catch unreachable;
|
const stats = self._factory._slab.getStats(self.arena) catch unreachable;
|
||||||
// stats.print() catch unreachable;
|
stats.print() catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.js.deinit();
|
self.js.deinit();
|
||||||
|
|||||||
@@ -21,12 +21,15 @@ const Writer = std.Io.Writer;
|
|||||||
|
|
||||||
const js = @import("../js/js.zig");
|
const js = @import("../js/js.zig");
|
||||||
const Page = @import("../Page.zig");
|
const Page = @import("../Page.zig");
|
||||||
|
const FactoryAllocationKind = @import("../Factory.zig").FactoryAllocationKind;
|
||||||
|
|
||||||
/// https://w3c.github.io/FileAPI/#blob-section
|
/// https://w3c.github.io/FileAPI/#blob-section
|
||||||
/// https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
/// https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
||||||
const Blob = @This();
|
const Blob = @This();
|
||||||
|
|
||||||
_type: Type,
|
_type: Type,
|
||||||
|
_allocation: FactoryAllocationKind,
|
||||||
|
|
||||||
/// Immutable slice of blob.
|
/// Immutable slice of blob.
|
||||||
/// Note that another blob may hold a pointer/slice to this,
|
/// Note that another blob may hold a pointer/slice to this,
|
||||||
/// so its better to leave the deallocation of it to arena allocator.
|
/// so its better to leave the deallocation of it to arena allocator.
|
||||||
@@ -78,6 +81,7 @@ pub fn init(
|
|||||||
|
|
||||||
return page._factory.create(Blob{
|
return page._factory.create(Blob{
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
|
._allocation = .standalone,
|
||||||
.slice = slice,
|
.slice = slice,
|
||||||
.mime = mime,
|
.mime = mime,
|
||||||
});
|
});
|
||||||
@@ -267,6 +271,7 @@ pub fn getSlice(
|
|||||||
|
|
||||||
return page._factory.create(Blob{
|
return page._factory.create(Blob{
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
|
._allocation = .standalone,
|
||||||
.slice = slice[start..end],
|
.slice = slice[start..end],
|
||||||
.mime = mime,
|
.mime = mime,
|
||||||
});
|
});
|
||||||
@@ -274,6 +279,7 @@ pub fn getSlice(
|
|||||||
|
|
||||||
return page._factory.create(Blob{
|
return page._factory.create(Blob{
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
|
._allocation = .standalone,
|
||||||
.slice = slice,
|
.slice = slice,
|
||||||
.mime = mime,
|
.mime = mime,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,12 +20,15 @@ const std = @import("std");
|
|||||||
const js = @import("../js/js.zig");
|
const js = @import("../js/js.zig");
|
||||||
|
|
||||||
const Page = @import("../Page.zig");
|
const Page = @import("../Page.zig");
|
||||||
|
const FactoryAllocationKind = @import("../Factory.zig").FactoryAllocationKind;
|
||||||
const EventTarget = @import("EventTarget.zig");
|
const EventTarget = @import("EventTarget.zig");
|
||||||
const String = @import("../../string.zig").String;
|
const String = @import("../../string.zig").String;
|
||||||
|
|
||||||
pub const Event = @This();
|
pub const Event = @This();
|
||||||
|
|
||||||
_type: Type,
|
_type: Type,
|
||||||
|
_allocation: FactoryAllocationKind,
|
||||||
|
|
||||||
_bubbles: bool = false,
|
_bubbles: bool = false,
|
||||||
_cancelable: bool = false,
|
_cancelable: bool = false,
|
||||||
_type_string: String,
|
_type_string: String,
|
||||||
@@ -65,6 +68,7 @@ pub fn init(typ: []const u8, opts_: ?Options, page: *Page) !*Event {
|
|||||||
|
|
||||||
return page._factory.create(Event{
|
return page._factory.create(Event{
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
|
._allocation = .standalone,
|
||||||
._bubbles = opts.bubbles,
|
._bubbles = opts.bubbles,
|
||||||
._time_stamp = time_stamp,
|
._time_stamp = time_stamp,
|
||||||
._cancelable = opts.cancelable,
|
._cancelable = opts.cancelable,
|
||||||
|
|||||||
@@ -21,12 +21,14 @@ const js = @import("../js/js.zig");
|
|||||||
|
|
||||||
const Page = @import("../Page.zig");
|
const Page = @import("../Page.zig");
|
||||||
const RegisterOptions = @import("../EventManager.zig").RegisterOptions;
|
const RegisterOptions = @import("../EventManager.zig").RegisterOptions;
|
||||||
|
const FactoryAllocationKind = @import("../Factory.zig").FactoryAllocationKind;
|
||||||
|
|
||||||
const Event = @import("Event.zig");
|
const Event = @import("Event.zig");
|
||||||
|
|
||||||
const EventTarget = @This();
|
const EventTarget = @This();
|
||||||
|
|
||||||
_type: Type,
|
_type: Type,
|
||||||
|
_allocation: FactoryAllocationKind,
|
||||||
|
|
||||||
pub const Type = union(enum) {
|
pub const Type = union(enum) {
|
||||||
node: *@import("Node.zig"),
|
node: *@import("Node.zig"),
|
||||||
|
|||||||
Reference in New Issue
Block a user