mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1775 from lightpanda-io/arena_blob
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) {
|
pub fn blob(_: *const Factory, arena: Allocator, child: anytype) !*@TypeOf(child) {
|
||||||
const allocator = self._slab.allocator();
|
|
||||||
|
|
||||||
// Special case: Blob has slice and mime fields, so we need manual setup
|
// Special case: Blob has slice and mime fields, so we need manual setup
|
||||||
const chain = try PrototypeChain(
|
const chain = try PrototypeChain(
|
||||||
&.{ Blob, @TypeOf(child) },
|
&.{ Blob, @TypeOf(child) },
|
||||||
).allocate(allocator);
|
).allocate(arena);
|
||||||
|
|
||||||
const blob_ptr = chain.get(0);
|
const blob_ptr = chain.get(0);
|
||||||
blob_ptr.* = .{
|
blob_ptr.* = .{
|
||||||
|
._arena = arena,
|
||||||
._type = unionInit(Blob.Type, chain.get(1)),
|
._type = unionInit(Blob.Type, chain.get(1)),
|
||||||
._slice = "",
|
._slice = "",
|
||||||
._mime = "",
|
._mime = "",
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ 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 Session = @import("../Session.zig");
|
||||||
|
|
||||||
const Mime = @import("../Mime.zig");
|
const Mime = @import("../Mime.zig");
|
||||||
|
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
/// 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();
|
||||||
@@ -31,6 +35,8 @@ pub const _prototype_root = true;
|
|||||||
|
|
||||||
_type: Type,
|
_type: Type,
|
||||||
|
|
||||||
|
_arena: Allocator,
|
||||||
|
|
||||||
/// 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.
|
||||||
@@ -69,6 +75,9 @@ pub fn initWithMimeValidation(
|
|||||||
validate_mime: bool,
|
validate_mime: bool,
|
||||||
page: *Page,
|
page: *Page,
|
||||||
) !*Blob {
|
) !*Blob {
|
||||||
|
const arena = try page.getArena(.{ .debug = "Blob" });
|
||||||
|
errdefer page.releaseArena(arena);
|
||||||
|
|
||||||
const options: InitOptions = maybe_options orelse .{};
|
const options: InitOptions = maybe_options orelse .{};
|
||||||
|
|
||||||
const mime: []const u8 = blk: {
|
const mime: []const u8 = blk: {
|
||||||
@@ -77,7 +86,7 @@ pub fn initWithMimeValidation(
|
|||||||
break :blk "";
|
break :blk "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const buf = try page.arena.dupe(u8, t);
|
const buf = try arena.dupe(u8, t);
|
||||||
|
|
||||||
if (validate_mime) {
|
if (validate_mime) {
|
||||||
// Full MIME parsing per MIME sniff spec (for Content-Type headers)
|
// Full MIME parsing per MIME sniff spec (for Content-Type headers)
|
||||||
@@ -99,7 +108,7 @@ pub fn initWithMimeValidation(
|
|||||||
|
|
||||||
const data = blk: {
|
const data = blk: {
|
||||||
if (maybe_blob_parts) |blob_parts| {
|
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");
|
const use_native_endings = std.mem.eql(u8, options.endings, "native");
|
||||||
try writeBlobParts(&w.writer, blob_parts, use_native_endings);
|
try writeBlobParts(&w.writer, blob_parts, use_native_endings);
|
||||||
|
|
||||||
@@ -109,11 +118,19 @@ pub fn initWithMimeValidation(
|
|||||||
break :blk "";
|
break :blk "";
|
||||||
};
|
};
|
||||||
|
|
||||||
return page._factory.create(Blob{
|
const self = try arena.create(Blob);
|
||||||
|
self.* = .{
|
||||||
|
._arena = arena,
|
||||||
._type = .generic,
|
._type = .generic,
|
||||||
._slice = data,
|
._slice = data,
|
||||||
._mime = mime,
|
._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);
|
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.
|
/// from a subset of the blob on which it's called.
|
||||||
pub fn slice(
|
pub fn slice(
|
||||||
self: *const Blob,
|
self: *const Blob,
|
||||||
maybe_start: ?i32,
|
start_: ?i32,
|
||||||
maybe_end: ?i32,
|
end_: ?i32,
|
||||||
maybe_content_type: ?[]const u8,
|
content_type_: ?[]const u8,
|
||||||
page: *Page,
|
page: *Page,
|
||||||
) !*Blob {
|
) !*Blob {
|
||||||
const mime: []const u8 = blk: {
|
const data = self._slice;
|
||||||
if (maybe_content_type) |content_type| {
|
|
||||||
if (content_type.len == 0) {
|
|
||||||
break :blk "";
|
|
||||||
}
|
|
||||||
|
|
||||||
break :blk try page.dupeString(content_type);
|
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)));
|
||||||
break :blk "";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = self._slice;
|
const end: usize = blk: {
|
||||||
if (maybe_start) |_start| {
|
const requested_end = end_ orelse break :blk data.len;
|
||||||
const start = blk: {
|
if (requested_end < 0) {
|
||||||
if (_start < 0) {
|
break :blk @max(start, data.len -| @abs(requested_end));
|
||||||
break :blk data.len -| @abs(_start);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break :blk @min(data.len, @as(u31, @intCast(_start)));
|
break :blk @min(data.len, @max(start, @as(u31, @intCast(requested_end))));
|
||||||
};
|
};
|
||||||
|
|
||||||
const end: usize = blk: {
|
return Blob.init(&.{data[start..end]}, .{ .type = content_type_ orelse "" }, page);
|
||||||
if (maybe_end) |_end| {
|
|
||||||
if (_end < 0) {
|
|
||||||
break :blk @max(start, data.len -| @abs(_end));
|
|
||||||
}
|
|
||||||
|
|
||||||
break :blk @min(data.len, @max(start, @as(u31, @intCast(_end))));
|
|
||||||
}
|
|
||||||
|
|
||||||
break :blk data.len;
|
|
||||||
};
|
|
||||||
|
|
||||||
return page._factory.create(Blob{
|
|
||||||
._type = .generic,
|
|
||||||
._slice = data[start..end],
|
|
||||||
._mime = mime,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return page._factory.create(Blob{
|
|
||||||
._type = .generic,
|
|
||||||
._slice = data,
|
|
||||||
._mime = mime,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the size of the Blob in bytes.
|
/// Returns the size of the Blob in bytes.
|
||||||
@@ -334,6 +325,8 @@ pub const JsApi = struct {
|
|||||||
pub const name = "Blob";
|
pub const name = "Blob";
|
||||||
pub const prototype_chain = bridge.prototypeChain();
|
pub const prototype_chain = bridge.prototypeChain();
|
||||||
pub var class_id: bridge.ClassId = undefined;
|
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, .{});
|
pub const constructor = bridge.constructor(Blob.init, .{});
|
||||||
|
|||||||
@@ -18,9 +18,11 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const Page = @import("../Page.zig");
|
|
||||||
const Blob = @import("Blob.zig");
|
|
||||||
const js = @import("../js/js.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();
|
const File = @This();
|
||||||
|
|
||||||
@@ -29,7 +31,13 @@ _proto: *Blob,
|
|||||||
|
|
||||||
// TODO: Implement File API.
|
// TODO: Implement File API.
|
||||||
pub fn init(page: *Page) !*File {
|
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 {
|
pub const JsApi = struct {
|
||||||
@@ -39,6 +47,8 @@ pub const JsApi = struct {
|
|||||||
pub const name = "File";
|
pub const name = "File";
|
||||||
pub const prototype_chain = bridge.prototypeChain();
|
pub const prototype_chain = bridge.prototypeChain();
|
||||||
pub var class_id: bridge.ClassId = undefined;
|
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, .{});
|
pub const constructor = bridge.constructor(File.init, .{});
|
||||||
|
|||||||
Reference in New Issue
Block a user