webapi: tighten DOM allocation lifetimes

Use the call arena only for the AbortSignal dependent list that must survive re-entrant abort handlers, and move scratch-only DOM reads to the local arena. Store BeforeUnloadEvent.returnValue in the event-owned arena so it remains valid without accumulating in the longer-lived frame arena.

These allocator changes bound temporary memory to the shortest safe lifetime while preserving existing Web API behavior. Add coverage for replacing BeforeUnloadEvent.returnValue.
This commit is contained in:
Francis Bouvier authored and Karl Seguin committed 2026-07-17 10:52:10 +08:00
1 parent 8f42b72d18
commit 50a896f4c0
4 files changed
+17 -4

No files matched your search

+13
View File
@@ -940,3 +940,16 @@
child.removeEventListener('click', listener);
}
</script>
<script id=beforeUnloadEventReturnValue>
{
const event = document.createEvent('BeforeUnloadEvent');
testing.expectEqual('', event.returnValue);
event.returnValue = 'first';
testing.expectEqual('first', event.returnValue);
event.returnValue = 'replacement';
testing.expectEqual('replacement', event.returnValue);
}
</script>
+1 -1
View File
@@ -106,7 +106,7 @@ pub fn abort(self: *AbortSignal, reason_: ?Reason, exec: *const Execution) !void
var to_dispatch: std.ArrayList(Dependend) = .{};
for (self._dependents.items) |dep| {
if (try dep.markAborted(self._reason, exec)) {
try to_dispatch.append(exec.arena, dep);
try to_dispatch.append(exec.call_arena, dep);
}
}
+1 -1
View File
@@ -380,7 +380,7 @@ pub fn getAccessKeyLabel(self: *HtmlElement, frame: *Frame) ![]const u8 {
if (codepoints != 1) {
return "";
}
return std.fmt.allocPrint(frame.call_arena, "Alt+{s}", .{value});
return std.fmt.allocPrint(frame.local_arena, "Alt+{s}", .{value});
}
pub fn getPopover(self: *HtmlElement) ?[]const u8 {
@@ -71,8 +71,8 @@ pub fn getReturnValue(self: *const BeforeUnloadEvent) []const u8 {
return self._return_value;
}
pub fn setReturnValue(self: *BeforeUnloadEvent, value: []const u8, frame: *Frame) !void {
self._return_value = try frame.dupeString(value);
pub fn setReturnValue(self: *BeforeUnloadEvent, value: []const u8) !void {
self._return_value = try self._proto._arena.dupe(u8, value);
}
pub const JsApi = struct {