mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-16 08:18:59 +00:00
shrink EventTarget back to 16
This commit is contained in:
@@ -96,7 +96,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)), ._allocation = self.memory };
|
ptr.* = .{ ._type = unionInit(T, self.get(1)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setMiddle(self: *const Self, comptime index: usize, comptime T: type) void {
|
fn setMiddle(self: *const Self, comptime index: usize, comptime T: type) void {
|
||||||
@@ -160,7 +160,6 @@ pub fn eventTarget(self: *Factory, child: anytype) !*@TypeOf(child) {
|
|||||||
const event_ptr = chain.get(0);
|
const event_ptr = chain.get(0);
|
||||||
event_ptr.* = .{
|
event_ptr.* = .{
|
||||||
._type = unionInit(EventTarget.Type, chain.get(1)),
|
._type = unionInit(EventTarget.Type, chain.get(1)),
|
||||||
._allocation = chain.memory,
|
|
||||||
};
|
};
|
||||||
chain.setLeaf(1, child);
|
chain.setLeaf(1, child);
|
||||||
|
|
||||||
@@ -180,7 +179,6 @@ pub fn event(self: *Factory, typ: []const u8, child: anytype) !*@TypeOf(child) {
|
|||||||
event_ptr.* = .{
|
event_ptr.* = .{
|
||||||
._type = unionInit(Event.Type, chain.get(1)),
|
._type = unionInit(Event.Type, chain.get(1)),
|
||||||
._type_string = try String.init(self._page.arena, typ, .{}),
|
._type_string = try String.init(self._page.arena, typ, .{}),
|
||||||
._allocation = chain.memory,
|
|
||||||
};
|
};
|
||||||
chain.setLeaf(1, child);
|
chain.setLeaf(1, child);
|
||||||
|
|
||||||
@@ -198,7 +196,6 @@ pub fn blob(self: *Factory, child: anytype) !*@TypeOf(child) {
|
|||||||
const blob_ptr = chain.get(0);
|
const blob_ptr = chain.get(0);
|
||||||
blob_ptr.* = .{
|
blob_ptr.* = .{
|
||||||
._type = unionInit(Blob.Type, chain.get(1)),
|
._type = unionInit(Blob.Type, chain.get(1)),
|
||||||
._allocation = chain.memory,
|
|
||||||
.slice = "",
|
.slice = "",
|
||||||
.mime = "",
|
.mime = "",
|
||||||
};
|
};
|
||||||
@@ -275,9 +272,34 @@ pub fn xhrEventTarget(self: *Factory, child: anytype) !*@TypeOf(child) {
|
|||||||
).create(allocator, child);
|
).create(allocator, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn hasChainRoot(comptime T: type) bool {
|
||||||
|
// Check if this is a root
|
||||||
|
if (@hasDecl(T, "_prototype_root")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no _proto field, we're at the top but not a recognized root
|
||||||
|
if (!@hasField(T, "_proto")) return false;
|
||||||
|
|
||||||
|
// Get the _proto field's type and recurse
|
||||||
|
const fields = @typeInfo(T).@"struct".fields;
|
||||||
|
inline for (fields) |field| {
|
||||||
|
if (std.mem.eql(u8, field.name, "_proto")) {
|
||||||
|
const ProtoType = reflect.Struct(field.type);
|
||||||
|
return hasChainRoot(ProtoType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn isChainType(comptime T: type) bool {
|
||||||
|
if (@hasField(T, "_proto")) return false;
|
||||||
|
return comptime hasChainRoot(T);
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
// We should always destroy from the leaf down.
|
// We should always destroy from the leaf down.
|
||||||
@@ -292,14 +314,48 @@ pub fn destroy(self: *Factory, value: anytype) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const chain_memory = self.destroyChain(value, true) orelse return;
|
if (comptime isChainType(S)) {
|
||||||
allocator.free(chain_memory);
|
self.destroyChain(value, true, 0, std.mem.Alignment.@"1");
|
||||||
|
} else {
|
||||||
|
self.destroyStandalone(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroyChain(self: *Factory, value: anytype, comptime first: bool) ?[]u8 {
|
pub fn destroyStandalone(self: *Factory, value: anytype) void {
|
||||||
|
const S = reflect.Struct(@TypeOf(value));
|
||||||
|
assert(!@hasDecl(S, "_prototype_root"));
|
||||||
|
|
||||||
|
const allocator = self._slab.allocator();
|
||||||
|
|
||||||
|
if (@hasDecl(S, "deinit")) {
|
||||||
|
// And it has a deinit, we'll call it
|
||||||
|
switch (@typeInfo(@TypeOf(S.deinit)).@"fn".params.len) {
|
||||||
|
1 => value.deinit(),
|
||||||
|
2 => value.deinit(self._page),
|
||||||
|
else => @compileLog(@typeName(S) ++ " has an invalid deinit function"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator.destroy(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroyChain(
|
||||||
|
self: *Factory,
|
||||||
|
value: anytype,
|
||||||
|
comptime first: bool,
|
||||||
|
old_size: usize,
|
||||||
|
old_align: std.mem.Alignment,
|
||||||
|
) void {
|
||||||
const S = reflect.Struct(@TypeOf(value));
|
const S = reflect.Struct(@TypeOf(value));
|
||||||
const allocator = self._slab.allocator();
|
const allocator = self._slab.allocator();
|
||||||
|
|
||||||
|
// aligns the old size to the alignment of this element
|
||||||
|
const current_size = std.mem.alignForward(usize, old_size, @alignOf(S));
|
||||||
|
const alignment = std.mem.Alignment.fromByteUnits(@alignOf(S));
|
||||||
|
|
||||||
|
const new_align = std.mem.Alignment.max(old_align, alignment);
|
||||||
|
const new_size = current_size + @sizeOf(S);
|
||||||
|
|
||||||
// This is initially called from a deinit. We don't want to call that
|
// This is initially called from a deinit. We don't want to call that
|
||||||
// same deinit. So when this is the first time destroyChain is called
|
// same deinit. So when this is the first time destroyChain is called
|
||||||
// we don't call deinit (because we're in that deinit)
|
// we don't call deinit (because we're in that deinit)
|
||||||
@@ -316,15 +372,22 @@ fn destroyChain(self: *Factory, value: anytype, comptime first: bool) ?[]u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (@hasField(S, "_proto")) {
|
if (@hasField(S, "_proto")) {
|
||||||
return self.destroyChain(value._proto, false);
|
self.destroyChain(value._proto, false, new_size, new_align);
|
||||||
} else if (@hasDecl(S, "JsApi")) {
|
} else if (@hasDecl(S, "JsApi")) {
|
||||||
// Doesn't have a _proto, but has a JsApi.
|
// Doesn't have a _proto, but has a JsApi.
|
||||||
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")) {
|
} else {
|
||||||
return value._allocation;
|
// no proto so this is the head of the chain.
|
||||||
} else return null;
|
// we use this as the ptr to the start of the chain.
|
||||||
|
// and we have summed up the length.
|
||||||
|
assert(@hasDecl(S, "_prototype_root"));
|
||||||
|
|
||||||
|
const memory_ptr: [*]const u8 = @ptrCast(value);
|
||||||
|
const len = std.mem.alignForward(usize, new_size, new_align.toByteUnits());
|
||||||
|
allocator.free(memory_ptr[0..len]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createT(self: *Factory, comptime T: type) !*T {
|
pub fn createT(self: *Factory, comptime T: type) !*T {
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ const Page = @import("../Page.zig");
|
|||||||
/// 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();
|
||||||
|
|
||||||
|
const _prototype_root = true;
|
||||||
_type: Type,
|
_type: Type,
|
||||||
_allocation: ?[]u8,
|
|
||||||
|
|
||||||
/// 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,
|
||||||
@@ -80,7 +80,6 @@ pub fn init(
|
|||||||
|
|
||||||
return page._factory.create(Blob{
|
return page._factory.create(Blob{
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
._allocation = null,
|
|
||||||
.slice = slice,
|
.slice = slice,
|
||||||
.mime = mime,
|
.mime = mime,
|
||||||
});
|
});
|
||||||
@@ -270,7 +269,6 @@ pub fn getSlice(
|
|||||||
|
|
||||||
return page._factory.create(Blob{
|
return page._factory.create(Blob{
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
._allocation = null,
|
|
||||||
.slice = slice[start..end],
|
.slice = slice[start..end],
|
||||||
.mime = mime,
|
.mime = mime,
|
||||||
});
|
});
|
||||||
@@ -278,7 +276,6 @@ pub fn getSlice(
|
|||||||
|
|
||||||
return page._factory.create(Blob{
|
return page._factory.create(Blob{
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
._allocation = null,
|
|
||||||
.slice = slice,
|
.slice = slice,
|
||||||
.mime = mime,
|
.mime = mime,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ const String = @import("../../string.zig").String;
|
|||||||
|
|
||||||
pub const Event = @This();
|
pub const Event = @This();
|
||||||
|
|
||||||
|
const _prototype_root = true;
|
||||||
_type: Type,
|
_type: Type,
|
||||||
_allocation: ?[]u8,
|
|
||||||
|
|
||||||
_bubbles: bool = false,
|
_bubbles: bool = false,
|
||||||
_cancelable: bool = false,
|
_cancelable: bool = false,
|
||||||
@@ -67,7 +67,6 @@ 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 = null,
|
|
||||||
._bubbles = opts.bubbles,
|
._bubbles = opts.bubbles,
|
||||||
._time_stamp = time_stamp,
|
._time_stamp = time_stamp,
|
||||||
._cancelable = opts.cancelable,
|
._cancelable = opts.cancelable,
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ const Event = @import("Event.zig");
|
|||||||
|
|
||||||
const EventTarget = @This();
|
const EventTarget = @This();
|
||||||
|
|
||||||
|
const _prototype_root = true;
|
||||||
_type: Type,
|
_type: Type,
|
||||||
_allocation: ?[]u8,
|
|
||||||
|
|
||||||
pub const Type = union(enum) {
|
pub const Type = union(enum) {
|
||||||
node: *@import("Node.zig"),
|
node: *@import("Node.zig"),
|
||||||
@@ -123,7 +123,7 @@ pub const JsApi = struct {
|
|||||||
const testing = @import("../../testing.zig");
|
const testing = @import("../../testing.zig");
|
||||||
test "WebApi: EventTarget" {
|
test "WebApi: EventTarget" {
|
||||||
// we create thousands of these per page. Nothing should bloat it.
|
// we create thousands of these per page. Nothing should bloat it.
|
||||||
try testing.expectEqual(32, @sizeOf(EventTarget));
|
try testing.expectEqual(16, @sizeOf(EventTarget));
|
||||||
|
|
||||||
try testing.htmlRunner("events.html", .{});
|
try testing.htmlRunner("events.html", .{});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user