mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 06:23:45 +00:00
Merge pull request #1428 from lightpanda-io/parser_arena_pool
Use ArenaPool when parsing HTML and for TextDecoder (with finalizer)
This commit is contained in:
@@ -737,7 +737,10 @@ fn pageDoneCallback(ctx: *anyopaque) !void {
|
|||||||
|
|
||||||
switch (self._parse_state) {
|
switch (self._parse_state) {
|
||||||
.html => |buf| {
|
.html => |buf| {
|
||||||
var parser = Parser.init(self.arena, self.document.asNode(), self);
|
const parse_arena = try self.getArena(.{ .debug = "Page.parse" });
|
||||||
|
defer self.releaseArena(parse_arena);
|
||||||
|
|
||||||
|
var parser = Parser.init(parse_arena, self.document.asNode(), self);
|
||||||
parser.parse(buf.items);
|
parser.parse(buf.items);
|
||||||
self._script_manager.staticScriptsDone();
|
self._script_manager.staticScriptsDone();
|
||||||
if (self._script_manager.isDone()) {
|
if (self._script_manager.isDone()) {
|
||||||
@@ -749,7 +752,11 @@ fn pageDoneCallback(ctx: *anyopaque) !void {
|
|||||||
},
|
},
|
||||||
.text => |*buf| {
|
.text => |*buf| {
|
||||||
try buf.appendSlice(self.arena, "</pre></body></html>");
|
try buf.appendSlice(self.arena, "</pre></body></html>");
|
||||||
var parser = Parser.init(self.arena, self.document.asNode(), self);
|
|
||||||
|
const parse_arena = try self.getArena(.{ .debug = "Page.parse" });
|
||||||
|
defer self.releaseArena(parse_arena);
|
||||||
|
|
||||||
|
var parser = Parser.init(parse_arena, self.document.asNode(), self);
|
||||||
parser.parse(buf.items);
|
parser.parse(buf.items);
|
||||||
self.documentIsComplete();
|
self.documentIsComplete();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ pub fn parseFromString(
|
|||||||
@"image/svg+xml",
|
@"image/svg+xml",
|
||||||
}, mime_type) orelse return error.NotSupported;
|
}, mime_type) orelse return error.NotSupported;
|
||||||
|
|
||||||
|
const arena = try page.getArena(.{ .debug = "DOMParser.parseFromString" });
|
||||||
|
defer page.releaseArena(arena);
|
||||||
|
|
||||||
return switch (target_mime) {
|
return switch (target_mime) {
|
||||||
.@"text/html" => {
|
.@"text/html" => {
|
||||||
// Create a new HTMLDocument
|
// Create a new HTMLDocument
|
||||||
@@ -61,7 +64,7 @@ pub fn parseFromString(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse HTML into the document
|
// Parse HTML into the document
|
||||||
var parser = Parser.init(page.arena, doc.asNode(), page);
|
var parser = Parser.init(arena, doc.asNode(), page);
|
||||||
parser.parse(normalized);
|
parser.parse(normalized);
|
||||||
|
|
||||||
if (parser.err) |pe| {
|
if (parser.err) |pe| {
|
||||||
@@ -78,7 +81,7 @@ pub fn parseFromString(
|
|||||||
|
|
||||||
// Parse XML into XMLDocument.
|
// Parse XML into XMLDocument.
|
||||||
const doc_node = doc.asNode();
|
const doc_node = doc.asNode();
|
||||||
var parser = Parser.init(page.arena, doc_node, page);
|
var parser = Parser.init(arena, doc_node, page);
|
||||||
parser.parseXML(html);
|
parser.parseXML(html);
|
||||||
|
|
||||||
if (parser.err) |pe| {
|
if (parser.err) |pe| {
|
||||||
|
|||||||
@@ -648,7 +648,10 @@ pub fn write(self: *Document, text: []const []const u8, page: *Page) !void {
|
|||||||
page._parse_mode = .document_write;
|
page._parse_mode = .document_write;
|
||||||
defer page._parse_mode = previous_parse_mode;
|
defer page._parse_mode = previous_parse_mode;
|
||||||
|
|
||||||
var parser = Parser.init(page.call_arena, fragment_node, page);
|
const arena = try page.getArena(.{ .debug = "Document.write" });
|
||||||
|
defer page.releaseArena(arena);
|
||||||
|
|
||||||
|
var parser = Parser.init(arena, fragment_node, page);
|
||||||
parser.parseFragment(html);
|
parser.parseFragment(html);
|
||||||
|
|
||||||
// Extract children from wrapper HTML element (html5ever wraps fragments)
|
// Extract children from wrapper HTML element (html5ever wraps fragments)
|
||||||
@@ -661,7 +664,7 @@ pub fn write(self: *Document, text: []const []const u8, page: *Page) !void {
|
|||||||
|
|
||||||
var it = if (first.is(Element.Html.Html) == null) fragment_node.childrenIterator() else first.childrenIterator();
|
var it = if (first.is(Element.Html.Html) == null) fragment_node.childrenIterator() else first.childrenIterator();
|
||||||
while (it.next()) |child| {
|
while (it.next()) |child| {
|
||||||
try children_to_insert.append(page.call_arena, child);
|
try children_to_insert.append(arena, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children_to_insert.items.len == 0) {
|
if (children_to_insert.items.len == 0) {
|
||||||
|
|||||||
@@ -281,8 +281,11 @@ pub fn insertAdjacentHTML(
|
|||||||
});
|
});
|
||||||
const doc_node = doc.asNode();
|
const doc_node = doc.asNode();
|
||||||
|
|
||||||
|
const arena = try page.getArena(.{ .debug = "HTML.insertAdjacentHTML" });
|
||||||
|
defer page.releaseArena(arena);
|
||||||
|
|
||||||
const Parser = @import("../../parser/Parser.zig");
|
const Parser = @import("../../parser/Parser.zig");
|
||||||
var parser = Parser.init(page.call_arena, doc_node, page);
|
var parser = Parser.init(arena, doc_node, page);
|
||||||
parser.parse(html);
|
parser.parse(html);
|
||||||
|
|
||||||
// Check if there's parsing error.
|
// Check if there's parsing error.
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ const Allocator = std.mem.Allocator;
|
|||||||
const TextDecoder = @This();
|
const TextDecoder = @This();
|
||||||
|
|
||||||
_fatal: bool,
|
_fatal: bool,
|
||||||
_ignore_bom: bool,
|
_page: *Page,
|
||||||
_arena: Allocator,
|
_arena: Allocator,
|
||||||
|
_ignore_bom: bool,
|
||||||
_stream: std.ArrayListUnmanaged(u8),
|
_stream: std.ArrayListUnmanaged(u8),
|
||||||
|
|
||||||
const Label = enum {
|
const Label = enum {
|
||||||
@@ -45,13 +46,23 @@ pub fn init(label_: ?[]const u8, opts_: ?InitOpts, page: *Page) !*TextDecoder {
|
|||||||
_ = std.meta.stringToEnum(Label, label) orelse return error.RangeError;
|
_ = std.meta.stringToEnum(Label, label) orelse return error.RangeError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const arena = try page.getArena(.{ .debug = "TextDecoder" });
|
||||||
|
errdefer page.releaseArena(arena);
|
||||||
|
|
||||||
const opts = opts_ orelse InitOpts{};
|
const opts = opts_ orelse InitOpts{};
|
||||||
return page._factory.create(TextDecoder{
|
const self = try arena.create(TextDecoder);
|
||||||
._arena = page.arena,
|
self.* = .{
|
||||||
|
._page = page,
|
||||||
|
._arena = arena,
|
||||||
._stream = .empty,
|
._stream = .empty,
|
||||||
._fatal = opts.fatal,
|
._fatal = opts.fatal,
|
||||||
._ignore_bom = opts.ignoreBOM,
|
._ignore_bom = opts.ignoreBOM,
|
||||||
});
|
};
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *TextDecoder, _: bool) void {
|
||||||
|
self._page.releaseArena(self._arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getEncoding(_: *const TextDecoder) []const u8 {
|
pub fn getEncoding(_: *const TextDecoder) []const u8 {
|
||||||
@@ -103,6 +114,8 @@ pub const JsApi = struct {
|
|||||||
pub const name = "TextDecoder";
|
pub const name = "TextDecoder";
|
||||||
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(TextDecoder.deinit);
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const constructor = bridge.constructor(TextDecoder.init, .{});
|
pub const constructor = bridge.constructor(TextDecoder.init, .{});
|
||||||
|
|||||||
Reference in New Issue
Block a user