Commit Graph

4556 Commits

Author SHA1 Message Date
Karl Seguin
f4a5f73ab2 Add v8 private object cache + Node.childNodes caching
Very simply, this PR ensures that:

  div.childNodes === div.childNodes

Previously, each invocation of childNodes would return a distinct object. Not
just inefficient, but incorrect.

Where this gets more complicated is the how.

The simple way to do this would be to have an optional `_child_nodes` field in
Node. When it's called the first time, we load and return it and, on subsequent
calls we can return it from the field directly.

But we generally avoid this pattern for data that we don't expect to be called
often relative to the number of instances. A page with 20K nodes _might_ see
.childNodes called on 1% of those, so storing a pointer in Nodes which isn't
going to be used isn't particularly memory efficient.

Instead, we have (historically) opted to store this in a page-level map/lookup.
This is used extensively for various element properties, e.g. the page
_element_class_lists lookup.

I recently abandoned work on v8 property caching
(https://github.com/lightpanda-io/browser/pull/1511). But then I looked into the
performance on a specific website with _a lot_ of DOMRect creation and I started
to think about both caching and pure-v8 DOM objects. So this PR became a
two-birds with one stone kind of deal. It re-introduces caching as a means to
solve the childNodes correctness. This uses 1 specific type of caching mechanism,
hooking into a v8::object's Private data map, but the code should be easily
extendable to support a faster (but less memory efficient, depending on the use
case) option: internal fields.
2026-02-15 11:34:01 +08:00
Karl Seguin
e61a4564ea Merge pull request #1545 from lightpanda-io/node_list_index
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
NodeList index fix + Node.childNode fix
2026-02-15 09:32:28 +08:00
Karl Seguin
e72edee1f2 Merge pull request #1548 from lightpanda-io/HTMLDListElement
Add HTMLDListElement
2026-02-15 07:45:38 +08:00
Karl Seguin
e8c150fcac Merge pull request #1544 from lightpanda-io/caller_function
Re-arrange Caller
2026-02-15 07:45:25 +08:00
Halil Durak
52418932b1 simpleZigValueToJs: support Uint8ClampedArray
Needed this to implement `ImageData#data` getter. This works differently than other typed arrays since returned object can be mutated from both Zig and JS ends.
2026-02-15 02:03:11 +03:00
Karl Seguin
4f81cb9333 Add more granular assertions
Trying to see how the "ScriptManager.Header buffer" assertion is failing. Either
`headerCallback` is being called multiple times, or the script is corrupt. By
adding a similar assertion in various places, we can hopefully narrow (a) what's
going on and (b) what code is involved.

Also, switched the BufferPool from DoublyLinkedList to SinglyLinkedList. Was
just reviewing this code (to see if the buffer could possibly become corrupt)
and realized this could be switched.
2026-02-14 20:01:09 +08:00
Karl Seguin
db46f47b96 Add HTMLDListElement
Fix names for ol and ul elements
2026-02-14 17:11:29 +08:00
Karl Seguin
edfe5594ba add more types to document.createEvent 2026-02-14 15:09:46 +08:00
Karl Seguin
f25e972594 NodeList index fix + Node.childNode fix
An index out of range request to a nodelist , e.g. childNodes[1000] now properly
returns a error.NotHandled error, which is given to v8 as a non-intercepted
property.

When a ChildNode node list is created from Node.childNode, we store the *Node
rather than its children. ChildNode is meant to be live, so if the node's
children changes, we should capture that.
2026-02-14 14:51:33 +08:00
Karl Seguin
d5488bdd42 Re-arrange Caller
This is preparatory work for re-introducing property caching and pure v8 WebAPIs

It does 3 things:

1 - It removes the duplication of method calling we had in Accessors and
    Functions type briges.

2 - It flattens the method-call chain. It used to be some code in bridge, then
    method, then _method. Most of the code is now in the same place. This will
    be important since caching requires the raw js_value, which we previously
    didn't expose from _method. Now, it's just there.

3 - Caller used to do everything. Then we introduced Local and a lot of Caller
    methods didn't need caller itself, they just needed &self.local. While those
    methods remain in Caller.zig, they now take a *const Local directly and thus
    can be called without Caller, making them usable without a Caller.
2026-02-14 14:22:46 +08:00
Karl Seguin
bbff64bc96 Merge pull request #1543 from lightpanda-io/zig_fmt
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
zig fmt
2026-02-14 14:20:43 +08:00
Karl Seguin
635afefdeb Merge pull request #1540 from lightpanda-io/tao_v8_storage
Optimize tao storage in v8 object.
2026-02-14 14:14:51 +08:00
Karl Seguin
fd3e67a0b4 zig fmt 2026-02-14 14:06:25 +08:00
Karl Seguin
729a6021ee update v8 dep 2026-02-14 14:06:03 +08:00
Karl Seguin
309f254c2c Optimize toa storage in v8 object.
We're currently using Get/SetInternalField to store our toa instance in v8. This
appears to be meant for v8 data itself, as it participates in the GC's
referencing counting. This is a bit obvious by the fact that it expects a
v8::Data, we we're able to do by wrapping our toa into a v8::External.

The Get/SetAlignedPointerFromInternalField seem specifically designed for toa,
as it takes a (void *) (thus, not requiring the external wrapper) and, from what
I understand is more efficient (presumably because the GC ignores it).

Depends on: https://github.com/lightpanda-io/zig-v8-fork/pull/149
2026-02-14 14:04:25 +08:00
Karl Seguin
5c37f04d64 Merge pull request #1539 from lightpanda-io/range_set_validation
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
Add missing validation to range setStart and setEnd
2026-02-14 07:03:27 +08:00
Karl Seguin
7c3dd8e852 Merge pull request #1538 from lightpanda-io/browser_arenas
Remove custom-arenas, use ArenaPool instead
2026-02-14 07:03:14 +08:00
Karl Seguin
66ddedbaf3 Merge pull request #1537 from lightpanda-io/input_click
Default behavior for input click (radio / checkbox).
2026-02-14 07:02:05 +08:00
Karl Seguin
7981b17897 Merge pull request #1541 from lightpanda-io/range_compare_boundary_points
Fix Range.compareBoundaryPoint
2026-02-14 07:01:52 +08:00
Pierre Tachoire
62137d47c8 Merge pull request #1533 from lightpanda-io/element_positions
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
Add various element position properties
2026-02-13 15:30:21 +01:00
Karl Seguin
e3b5437f61 fix test to match swapped (correct) implementation 2026-02-13 16:28:53 +08:00
Karl Seguin
934693924e Fix Range.compareBoundaryPoint
START_TO_END and END_TO_START had their logic swapped. This fixes the remaining
862 failing cases in dom/ranges/Range-compareBoundaryPoints.html
2026-02-13 15:06:17 +08:00
Muki Kiboigo
308fd92a46 chunking robot store hashing 2026-02-12 22:55:40 -08:00
Karl Seguin
da1eb71ad0 Add missing validation to Range.comparePoint
Also re-order the validation to match what  WPT expects. Fixes all cases in
dom/ranges/Range-comparePoint.html
2026-02-13 14:54:43 +08:00
Muki Kiboigo
576dbb7ce6 switch to iterative match solving 2026-02-12 22:54:35 -08:00
Muki Kiboigo
d0c381b3df partial compilation of robot rules 2026-02-12 22:32:29 -08:00
Muki Kiboigo
55178a81c6 skip empty disallow rules during robots parsing 2026-02-12 22:08:16 -08:00
Muki Kiboigo
249308380b no more longest match tracking in robots 2026-02-12 22:07:04 -08:00
Karl Seguin
d91bec08c3 Add missing validation to range setStart and setEnd
Fixes the remaining failing cases (400!) of WPT dom/ranges/Range-set.html
2026-02-13 13:47:26 +08:00
Karl Seguin
e23ef4b0be Remove custom-arenas, use ArenaPool instead
This removes the browser-specific arenas (session, transfer, page, call) in
favor of the arena pool.

This is a bit of a win-lose commit. It exists as (the last?) step before I can
really start working on frames. Frames will require their own "page" and "call"
arenas, so there isn't just 1 per browser now, but rather N, where N is the
number of frames + 1 page. This change was already done for Contexts when
ExecutionWorld was removed, and the idea is the same: making these units more
self contained so to support cases where we break out of the "1" model we
currently have (1 browser, 1 session, 1 page, 1 context, ...).

But it's a bit of a step backwards because the ArenaPool is dumb and just resets
everything to a single hard-coded (for now) value: 16KB. But in my mind, an
arena that's used for 1 thing (e.g. the page or call arenas) is more likely to
be well-sized for that specific role in the future, even on a different
page/navigate.

I think ultimately, we'll move to an ArenaPool that has different levels, e.g.
acquire() and acquireLarge() which can reset to different sizes, so that a page
arena can use acquireLarge() and retain a larger amount of memory between use.
2026-02-13 12:34:27 +08:00
Karl Seguin
6037521c49 Default behavior for input click (radio / checkbox).
This wasn't 100% intuitive to me. At the start of the event, the input is
immediately toggled. But at any point during dispatching, the default behavior
can be suppressed. So the state of the input's check during dispatching captures
the "intent" of the click. But it's possible for one listener to see that
input.checked == true even though, by the end of dispatching, input.checked ==
false because some other listener called preventDefault().

To support this, we need to capture the "current" state so that, if we need to
rollback, we can. For radio buttons, this "current" state includes capturing
the currently checked radio (if any).
2026-02-13 11:06:46 +08:00
Pierre Tachoire
a27fac3677 Merge pull request #1535 from lightpanda-io/wp/mrdimidium/ram-e2e-tests
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
ci: fix path
2026-02-12 16:04:40 +01:00
Pierre Tachoire
21f2eb664e ci: fix path 2026-02-12 15:44:28 +01:00
Pierre Tachoire
81546ef4b0 Merge pull request #1534 from lightpanda-io/wp/mrdimidium/ram-e2e-tests 2026-02-12 13:32:15 +01:00
Karl Seguin
4b90c8fd45 Add various element position properties
clientTop, clientLeft, scrollTop, scrollLeft, scrollHeight, scrollWidth,
offsetTop, offsetLeft, offsetWidth, offsetHeight.

These are all dummy implementation that hook, as much as possible, into what
layout information we have.

Explicitly set scroll information is stored on the page.
2026-02-12 19:30:29 +08:00
Pierre Tachoire
c643fb8aac ci: fix var name 2026-02-12 12:07:15 +01:00
Pierre Tachoire
0cae6ceca3 Merge pull request #1510 from lightpanda-io/wp/mrdimidium/ram-e2e-tests
Use cgroups for RAM mesurement
2026-02-12 11:55:02 +01:00
Karl Seguin
5cde59b53c Merge pull request #1528 from lightpanda-io/remove_recurise_curl_calls
Remove potential recursive abort call in curl
2026-02-12 18:42:09 +08:00
Pierre Tachoire
7df67630af ci: add cg_mem_peak into the tracked results 2026-02-12 11:33:52 +01:00
Karl Seguin
0c89dca261 When _not_ in a libcurl callback, deinit the transfer normally 2026-02-12 18:29:35 +08:00
Pierre Tachoire
6b953b8793 ci: keep both vm and cg memory regression tests 2026-02-12 11:24:59 +01:00
Karl Seguin
0d1defcf27 Merge pull request #1522 from lightpanda-io/remove_page_reset
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Remove Page.reset
2026-02-12 17:47:13 +08:00
Pierre Tachoire
c1db9c19b3 Merge pull request #1532 from lightpanda-io/document_scrollingElement
Add document.scrollingElement read-only property
2026-02-12 09:49:16 +01:00
Pierre Tachoire
95487755ed Merge pull request #1531 from lightpanda-io/dom_token_list_compat
Improve compliance of DOMTokenList
2026-02-12 09:49:09 +01:00
Pierre Tachoire
4813469659 Merge pull request #1530 from lightpanda-io/node_contains_null
Allow node.contains(null) (false), per spec
2026-02-12 09:48:14 +01:00
Karl Seguin
4dfd357c0b Merge pull request #1529 from lightpanda-io/get_elements_by_tag_name_ns
Get elements by tag name ns
2026-02-12 16:41:56 +08:00
Karl Seguin
4ca0486518 Add document.scrollingElement read-only property
From MDN: In standards mode, this is the root element of the document,
document.documentElement.

Easy enough.
2026-02-12 14:10:38 +08:00
Karl Seguin
b139c05960 Improve compliance of DOMTokenList
1 - Make element.classList settable
2 - On replace, validate in expected order
3 - On replace, fire mutation observer even if new == old
4 - On replace, handle duplicate values
2026-02-12 14:07:31 +08:00
Karl Seguin
3d32759030 Allow node.contains(null) (false), per spec 2026-02-12 12:39:07 +08:00
Karl Seguin
badfe39a3d Refactor common Document and Element methods into Node 2026-02-12 12:31:05 +08:00