mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Use arena from ArenaPool for Blob (and File)
This commit is contained in:
@@ -247,16 +247,15 @@ fn eventInit(arena: Allocator, typ: String, value: anytype) !Event {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn blob(self: *Factory, child: anytype) !*@TypeOf(child) {
|
||||
const allocator = self._slab.allocator();
|
||||
|
||||
pub fn blob(_: *const Factory, arena: Allocator, child: anytype) !*@TypeOf(child) {
|
||||
// Special case: Blob has slice and mime fields, so we need manual setup
|
||||
const chain = try PrototypeChain(
|
||||
&.{ Blob, @TypeOf(child) },
|
||||
).allocate(allocator);
|
||||
).allocate(arena);
|
||||
|
||||
const blob_ptr = chain.get(0);
|
||||
blob_ptr.* = .{
|
||||
._arena = arena,
|
||||
._type = unionInit(Blob.Type, chain.get(1)),
|
||||
._slice = "",
|
||||
._mime = "",
|
||||
|
||||
@@ -21,8 +21,12 @@ const Writer = std.Io.Writer;
|
||||
|
||||
const js = @import("../js/js.zig");
|
||||
const Page = @import("../Page.zig");
|
||||
const Session = @import("../Session.zig");
|
||||
|
||||
const Mime = @import("../Mime.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
/// https://w3c.github.io/FileAPI/#blob-section
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
||||
const Blob = @This();
|
||||
@@ -31,6 +35,8 @@ pub const _prototype_root = true;
|
||||
|
||||
_type: Type,
|
||||
|
||||
_arena: Allocator,
|
||||
|
||||
/// Immutable slice of blob.
|
||||
/// Note that another blob may hold a pointer/slice to this,
|
||||
/// so its better to leave the deallocation of it to arena allocator.
|
||||
@@ -69,6 +75,9 @@ pub fn initWithMimeValidation(
|
||||
validate_mime: bool,
|
||||
page: *Page,
|
||||
) !*Blob {
|
||||
const arena = try page.getArena(.{ .debug = "Blob" });
|
||||
errdefer page.releaseArena(arena);
|
||||
|
||||
const options: InitOptions = maybe_options orelse .{};
|
||||
|
||||
const mime: []const u8 = blk: {
|
||||
@@ -77,7 +86,7 @@ pub fn initWithMimeValidation(
|
||||
break :blk "";
|
||||
}
|
||||
|
||||
const buf = try page.arena.dupe(u8, t);
|
||||
const buf = try arena.dupe(u8, t);
|
||||
|
||||
if (validate_mime) {
|
||||
// Full MIME parsing per MIME sniff spec (for Content-Type headers)
|
||||
@@ -99,7 +108,7 @@ pub fn initWithMimeValidation(
|
||||
|
||||
const data = blk: {
|
||||
if (maybe_blob_parts) |blob_parts| {
|
||||
var w: Writer.Allocating = .init(page.arena);
|
||||
var w: Writer.Allocating = .init(arena);
|
||||
const use_native_endings = std.mem.eql(u8, options.endings, "native");
|
||||
try writeBlobParts(&w.writer, blob_parts, use_native_endings);
|
||||
|
||||
@@ -109,11 +118,19 @@ pub fn initWithMimeValidation(
|
||||
break :blk "";
|
||||
};
|
||||
|
||||
return page._factory.create(Blob{
|
||||
const self = try arena.create(Blob);
|
||||
self.* = .{
|
||||
._arena = arena,
|
||||
._type = .generic,
|
||||
._slice = data,
|
||||
._mime = mime,
|
||||
});
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Blob, shutdown: bool, session: *Session) void {
|
||||
_ = shutdown;
|
||||
session.releaseArena(self._arena);
|
||||
}
|
||||
|
||||
const largest_vector = @max(std.simd.suggestVectorLength(u8) orelse 1, 8);
|
||||
@@ -264,57 +281,31 @@ pub fn bytes(self: *const Blob, page: *Page) !js.Promise {
|
||||
/// from a subset of the blob on which it's called.
|
||||
pub fn slice(
|
||||
self: *const Blob,
|
||||
maybe_start: ?i32,
|
||||
maybe_end: ?i32,
|
||||
maybe_content_type: ?[]const u8,
|
||||
start_: ?i32,
|
||||
end_: ?i32,
|
||||
content_type_: ?[]const u8,
|
||||
page: *Page,
|
||||
) !*Blob {
|
||||
const mime: []const u8 = blk: {
|
||||
if (maybe_content_type) |content_type| {
|
||||
if (content_type.len == 0) {
|
||||
break :blk "";
|
||||
}
|
||||
|
||||
break :blk try page.dupeString(content_type);
|
||||
}
|
||||
|
||||
break :blk "";
|
||||
};
|
||||
|
||||
const data = self._slice;
|
||||
if (maybe_start) |_start| {
|
||||
const start = blk: {
|
||||
if (_start < 0) {
|
||||
break :blk data.len -| @abs(_start);
|
||||
}
|
||||
|
||||
break :blk @min(data.len, @as(u31, @intCast(_start)));
|
||||
const start = blk: {
|
||||
const requested_start = start_ orelse break :blk 0;
|
||||
if (requested_start < 0) {
|
||||
break :blk data.len -| @abs(requested_start);
|
||||
}
|
||||
break :blk @min(data.len, @as(u31, @intCast(requested_start)));
|
||||
};
|
||||
|
||||
const end: usize = blk: {
|
||||
if (maybe_end) |_end| {
|
||||
if (_end < 0) {
|
||||
break :blk @max(start, data.len -| @abs(_end));
|
||||
const requested_end = end_ orelse break :blk data.len;
|
||||
if (requested_end < 0) {
|
||||
break :blk @max(start, data.len -| @abs(requested_end));
|
||||
}
|
||||
|
||||
break :blk @min(data.len, @max(start, @as(u31, @intCast(_end))));
|
||||
}
|
||||
|
||||
break :blk data.len;
|
||||
break :blk @min(data.len, @max(start, @as(u31, @intCast(requested_end))));
|
||||
};
|
||||
|
||||
return page._factory.create(Blob{
|
||||
._type = .generic,
|
||||
._slice = data[start..end],
|
||||
._mime = mime,
|
||||
});
|
||||
}
|
||||
|
||||
return page._factory.create(Blob{
|
||||
._type = .generic,
|
||||
._slice = data,
|
||||
._mime = mime,
|
||||
});
|
||||
return Blob.init(&.{data[start..end]}, .{ .type = content_type_ orelse "" }, page);
|
||||
}
|
||||
|
||||
/// Returns the size of the Blob in bytes.
|
||||
@@ -334,6 +325,8 @@ pub const JsApi = struct {
|
||||
pub const name = "Blob";
|
||||
pub const prototype_chain = bridge.prototypeChain();
|
||||
pub var class_id: bridge.ClassId = undefined;
|
||||
pub const weak = true;
|
||||
pub const finalizer = bridge.finalizer(Blob.deinit);
|
||||
};
|
||||
|
||||
pub const constructor = bridge.constructor(Blob.init, .{});
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const Page = @import("../Page.zig");
|
||||
const Blob = @import("Blob.zig");
|
||||
const js = @import("../js/js.zig");
|
||||
const Page = @import("../Page.zig");
|
||||
const Session = @import("../Session.zig");
|
||||
|
||||
const Blob = @import("Blob.zig");
|
||||
|
||||
const File = @This();
|
||||
|
||||
@@ -29,7 +31,13 @@ _proto: *Blob,
|
||||
|
||||
// TODO: Implement File API.
|
||||
pub fn init(page: *Page) !*File {
|
||||
return page._factory.blob(File{ ._proto = undefined });
|
||||
const arena = try page.getArena(.{ .debug = "File" });
|
||||
errdefer page.releaseArena(arena);
|
||||
return page._factory.blob(arena, File{ ._proto = undefined });
|
||||
}
|
||||
|
||||
pub fn deinit(self: *File, shutdown: bool, session: *Session) void {
|
||||
self._proto.deinit(shutdown, session);
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
@@ -39,6 +47,8 @@ pub const JsApi = struct {
|
||||
pub const name = "File";
|
||||
pub const prototype_chain = bridge.prototypeChain();
|
||||
pub var class_id: bridge.ClassId = undefined;
|
||||
pub const weak = true;
|
||||
pub const finalizer = bridge.finalizer(File.deinit);
|
||||
};
|
||||
|
||||
pub const constructor = bridge.constructor(File.init, .{});
|
||||
|
||||
Reference in New Issue
Block a user