3875 Commits

Author SHA1 Message Date
Karl Seguin
3c635532c4 Merge pull request #1426 from lightpanda-io/update_page_js
Some checks are pending
e2e-test / zig build release (push) Waiting to run
e2e-test / demo-scripts (push) Blocked by required conditions
e2e-test / cdp-and-hyperfine-bench (push) Blocked by required conditions
e2e-test / perf-fmt (push) Blocked by required conditions
e2e-test / browser fetch (push) Blocked by required conditions
zig-test / zig test (push) Waiting to run
zig-test / perf-fmt (push) Blocked by required conditions
Update page.js based on the current context.
2026-02-04 08:51:53 +08:00
Karl Seguin
f8703bf884 Merge pull request #1459 from lightpanda-io/browser_context_arenas
Add a dedicated browser_context and page_arena to CDP.
2026-02-04 07:51:35 +08:00
Karl Seguin
eea3aa7a27 Merge pull request #1457 from lightpanda-io/arena_pool_free_list_len
Properly maintain the ArenaPool's free_list_len
2026-02-04 07:50:33 +08:00
Nikolay Govorov
6eff448508 Merge pull request #1464 from lightpanda-io/wp/mrdimidium/update-zig-v8-fork
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 (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Use asan/tsan for building v8
2026-02-03 16:18:23 +00:00
Nikolay Govorov
eb8cac5980 Use asan/tsan for building v8 2026-02-03 16:01:18 +00:00
Karl Seguin
1a4086c98c de-duplicate context shutdown in isolated worl deinit 2026-02-03 23:04:44 +08:00
Karl Seguin
5c91076660 Merge pull request #1458 from lightpanda-io/tweaks
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 (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
A few small tweaks
2026-02-03 20:09:38 +08:00
Karl Seguin
5467b8dd0d A few small tweaks
1 - Embed Page into Session, avoids having to allocate/deallocate the page
2 - Fix false-positive arena pool leak detection
3 - On form submit, pre-check if navigation will allowed before building the
    contents
4 - Make sure QueuedNavigation structure isn't use after page is removed
2026-02-03 20:07:47 +08:00
Karl Seguin
d46a9d6286 Merge pull request #1462 from lightpanda-io/check_for_leaks_after_all_releases
Only check for arena leaks AFTER we've triggered all releases
2026-02-03 18:43:40 +08:00
Karl Seguin
2fa7810128 Only check for arena leaks AFTER we've triggered all releases
We already did this for the Context, but shutting down the HTTP client can also
release resources.
2026-02-03 18:31:04 +08:00
Karl Seguin
c07b83335b add a few comments 2026-02-03 15:58:29 +08:00
Karl Seguin
7e575c501a Add a dedicated browser_context and page_arena to CDP.
The BrowserContext currently uses 3 arenas:
1 - Command-specific, which is like the call_arena, but for the processing of a
    single CDP command
2 - Notification-specific, which is similar, but for the processing of a single
    internal notification event
3 - Arena, which is just the session arena and lives for the duration of the
    BrowseContext/Session

This is pretty coarse and can results in significant memory accumulation if a
browser context is re-used for multiple navigations.

This commit introduces 3 changes:
1 - Rather than referencing Session.arena, the BrowerContext.arena is now its
    own arena. This doesn't really change anything, but it does help keep things
    a bit better separated.

2 - Introduces a page_arena (not to be confused with Page.arena). This arena
    exists for the duration of a 1 page, i.e. it's cleared when the
    BrowserContext receives the page_created internal notification. The
    `captured_responses` now uses this arena, which means captures only exist
    for the duration of the current page. This appears to be consistent with
    how chrome behaves (In fact, Chrome seems even more aggressive and doesn't
    appear to make any guarantees around captured responses). CDP refers to this
    lifetime as a "renderer" and has an experimental message, which we don't
    support, `Network.configureDurableMessages` to control this.

3 - Isolated Worlds are now more self contained with an arena from the ArenaPool.

There are currently 2 places where the BrowserContext.arena is still used:
1 - the isolated_world list
2 - the custom headers

Although this could be long lived, I believe the above is ok. We should just
really think twice whenever we want to use it for anything else.
2026-02-03 15:48:27 +08:00
Karl Seguin
933e2fb0ef Properly maintain the ArenaPool's free_list_len 2026-02-03 13:08:53 +08:00
Karl Seguin
8d51383fb2 Merge pull request #1450 from lightpanda-io/pluginarray_placeholder
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 (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Add Plugin and PluginArray placeholders
2026-02-03 07:10:46 +08:00
Karl Seguin
80f4c83b83 Merge pull request #1453 from lightpanda-io/xhr_arraybuffer
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 (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
add 'arraybuffer' responseType to XHR
2026-02-02 21:55:10 +08:00
Karl Seguin
0d739e4af7 Merge pull request #1446 from lightpanda-io/module_promise
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 (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
When loading a module, make sure we have a module_promise
2026-02-02 18:29:50 +08:00
Karl Seguin
58f9027002 Merge pull request #1454 from lightpanda-io/element_replaceWith
implement Element.replaceWith
2026-02-02 17:56:25 +08:00
Karl Seguin
990f2e2892 Merge pull request #1455 from lightpanda-io/element_scrollIntoView
add dummy scrollIntoView
2026-02-02 17:56:07 +08:00
Karl Seguin
ce7989c171 add dummy scrollIntoView 2026-02-02 16:41:39 +08:00
Karl Seguin
4efb0229d4 implement Element.replaceWith 2026-02-02 16:04:59 +08:00
Karl Seguin
5dd6dc2d69 per-context scheduler 2026-02-02 12:40:54 +08:00
Karl Seguin
20931eb9d6 update page.js on context.deinit 2026-02-02 12:22:00 +08:00
Karl Seguin
c11fa122af Update page.js based on the current context.
page.js currently always references the page context. But through the inspector
JavaScript can be executed in different contexts. When we go from V8->Zig we
correctly capture the current context within the caller's Local. And, because of
this, mapping or anything else that happens against local.ctx, happens in the
right context.

EXCEPT...our code still accesses page.js. So you can have a v8->zig call
happening in Context-2, and our Zig call then tries to do something on Context-1
via page.js.

I'm introducing a change that updates page.js based on the current Caller and
restores it at the end of the Caller. This change is super small, but
potentially has major impact. It's hard to imagine that we haven't run into
problems with this before, and it's hard to imagine what problems this change
might introduce. Certainly, if anyone copies page.js, they'll be in for a rude
surprise, but i don't think we do that anywhere.
2026-02-02 12:22:00 +08:00
Karl Seguin
e9141c8300 Handle more partial-load states + fix possible dangling pointer.
==Fix 1==
The problem flow:
1 - The module is dynamically imported, this creates a cache entry with no
module and no module_promise, and starts an async fetch.

2 - Before dynamicModuleSourceCallback fires (from step 1 above), the same
module is imported as a child of a call graph, i.e. via resolveModuleCallback.
Here the module is compiled, but never evaluated (we only evaluate the root
module). This is where things start to go sour. Our cache entry now has a
module, but no module_promise.

3 - The async fetch completes and calls dynamicModuleSourceCallback which call
Context.module. This returns early (the module is already cached thanks to
step 2). But it then calls resolveDynamicModule which (a) has a module and (b)
no module_promise.

Our fix works because, if Context.module finds the cached module (from step 2),
it now also checks for the module_promise. If it doesn't find it, it evaluates
the module (which sets it).

I've since expanded the code to handle more intermediary states.

The original PR had:

if (gop.value_ptr.module_promise == null) {
    const mod = local.toLocal(cache_mod);
    if (mod.getStatus() == .kInstantiated) {
        return self.evaluateModule(want_result, mod, url, true);
    }
}

But now the code is:

if (gop.value_ptr.module_promise == null) {
    const mod = local.toLocal(cache_mod);
    if (mod.getStatus() == .kUninstantiated and try mod.instantiate(resolveModuleCallback) == false) {
        return error.ModuleInstantiationError;
    }
    return self.evaluateModule(want_result, mod, url, true);
}

It seems that v8 handles double-instantiation and double-evaluations safely.

Handle more partial-load states.
Handle more partial-load states + fix possible dangling pointer.

==Fix 2==
We were using `gop` after potentially writing to the map (via a nested call to
mod.evaluate()). We now re-fetch the map entry to be able to safely write to it
2026-02-02 12:12:21 +08:00
Karl Seguin
1d03b688d9 When loading a module, make sure we have a module_promise
Currently, when loading a module, if the module is found in the cache, it's
immediately returned. However, that can result in a timing issue where the
module is cached, but not evaluated, and doesn't have an associated promise.

This commit tries to ensure a module is always evaluated and that the cache
entry has a module promise.

This might fix an crash handler issue. I couldn't reproduce the issue though.
I believe it requires specific timing which is hard to reproduce in a test.
2026-02-02 11:13:59 +08:00
Karl Seguin
176d42f625 add 'arraybuffer' responseType to XHR 2026-02-02 07:45:21 +08:00
Karl Seguin
7c98a27c53 Merge pull request #1452 from lightpanda-io/css_escape
Some checks failed
e2e-test / zig build release (push) Has been cancelled
zig-test / zig test (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 / 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
improve correctness of CSS.escape
2026-01-31 19:16:09 +08:00
Karl Seguin
020b30783e Merge pull request #1451 from lightpanda-io/xhr_fanalizer
Don't release XHR object until request complete
2026-01-31 19:15:58 +08:00
Pierre Tachoire
fafbdb0714 Merge pull request #1449 from lightpanda-io/scriptmanager-referer 2026-01-31 10:07:18 +01:00
Karl Seguin
466cdb4ee7 improve correctness of CSS.escape 2026-01-31 10:55:11 +08:00
Karl Seguin
fa66f0b509 Don't release XHR object until request complete
We previously figured that we could release the XHR object as soon as the JS
reference was out of scope. But the callbacks could still exist and thus the
XHR request should proceed.

This commit ensures the XHR instance remains valid so long as we have an active
request.

Might help with https://github.com/lightpanda-io/browser/issues/1448 but I can't
reliably reproduce this, so I'm not 100% sure it resolve the issue. That bug
appears to be caused by some timing interaction between the underlying HTTP
request and the v8 GC.
2026-01-31 10:31:16 +08:00
Karl Seguin
12a566c07e Merge pull request #1445 from lightpanda-io/schedule_task_finalizer
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 (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Allow [schedule] tasks to have finalizers
2026-01-31 07:06:24 +08:00
Karl Seguin
bf7a1c6b1f Merge pull request #1444 from lightpanda-io/inspector_rework
Rework Inspector usage
2026-01-31 07:06:11 +08:00
Karl Seguin
55891aa5f8 Add Plugin and PluginArray placeholders 2026-01-31 07:05:28 +08:00
Karl Seguin
7c0acd9fcb Merge pull request #1447 from lightpanda-io/exception_errors
Handle catching exception error objects
2026-01-31 06:41:37 +08:00
Pierre Tachoire
333f1e2c47 use page's headerForRequest with fetch and XHR 2026-01-30 18:18:20 +01:00
Pierre Tachoire
9d30cdfefc add HTTP headers referer for script manager requests 2026-01-30 18:16:33 +01:00
Karl Seguin
324f6fe16e Handle catching exception error objects
https://github.com/lightpanda-io/browser/issues/1443
2026-01-30 18:38:22 +08:00
Karl Seguin
5d96304332 Allow [schedule] tasks to have finalizers
There's no guarantee that a task will ever be run. A page can be shutdown by
the user or timeout or an error. Scheduler cleanup relies on the underlying
page.arena. This forces all tasks to rely on the page.arena as they have no way
to clean themselves.

This commit allows tasks to register a finalizer which is guaranteed to be
called when the scheduler is shutdown.

The window ScheduleCallback, PostMessageCallback now use an arena from the
ArenaPool rather than the page.arena and use the task finalizer to ensure the
arena is released on shutdown.
2026-01-30 17:23:03 +08:00
Pierre Tachoire
e6e32b5fd2 Merge pull request #1442 from lightpanda-io/disable_debug_crash_report
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 (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
2026-01-30 10:14:01 +01:00
Karl Seguin
181f265de5 Rework Inspector usage
V8's inspector world is made up of 4 components: Inspector, Client, Channel and
Session. Currently, we treat all 4 components as a single unit which is tied to
the lifetime of CDP BrowserContext - or, loosely speaking, 1 "Inspector Unit"
per page / v8::Context.

According to https://web.archive.org/web/20210622022956/https://hyperandroid.com/2020/02/12/v8-inspector-from-an-embedder-standpoint/
and conversation with Gemini, it's more typical to have 1 inspector per isolate.
The general breakdown is the Inspector is the top-level manager, the Client is
our implementation which control how the Inspector works (its function we expose
that v8 calls into). These should be tied to the Isolate. Channels and Sessions
are more closely tied to Context, where the Channel is v8->zig and the Session
us zig->v8.

This PR does a few things
1 - It creates 1 Inspector and Client per Isolate (Env.js)
2 - It creates 1 Session/Channel per BrowserContext
3 - It merges v8::Session and v8::Channel into Inspector.Session
4 - It moves the Inspector instance directly into the Env
5 - BrowserContext interacts with the Inspector.Session, not the Inspector

4 is arguably unnecessary with respect to the main goal of this commit, but
the end-goal is to tighten the integration. Specifically, rather than CDP having
to inform the inspector that a context was created/destroyed, the Env which
manages Contexts directly (https://github.com/lightpanda-io/browser/pull/1432)
and which now has direct access to the Inspector, is now equipped to keep this
in sync.
2026-01-30 15:59:33 +08:00
Karl Seguin
e5fc8bb27c Disable crash report in debug
Crashing when developing is more noise than signal
2026-01-30 07:06:09 +08:00
Karl Seguin
34dda780d9 Merge pull request #1441 from lightpanda-io/set_attribute_to_string_api
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 (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
fix setAttribute for new toString API
2026-01-30 07:05:29 +08:00
Karl Seguin
c7cf4eeb7a fix setAttribute for new toString API 2026-01-30 07:00:33 +08:00
Karl Seguin
a6e5d9f6dc Merge pull request #1439 from lightpanda-io/setAttribute-non-string
accept js.Value for element.setAttribute
2026-01-30 06:58:28 +08:00
Karl Seguin
ea1017584e Merge pull request #1433 from lightpanda-io/js_string
Cleanup js -> string
2026-01-30 06:55:40 +08:00
Karl Seguin
6aef32d7a8 Merge pull request #1438 from lightpanda-io/update_public_suffix_list
Update the public suffix list
2026-01-30 06:55:26 +08:00
Karl Seguin
4a1d71b6b8 Merge pull request #1437 from lightpanda-io/remove_unused
Remove unused import
2026-01-30 06:55:11 +08:00
Karl Seguin
a18b61cb1d Merge pull request #1432 from lightpanda-io/remove_execution_world
Remove js.ExecutionWorld
2026-01-30 06:54:55 +08:00
Karl Seguin
e31e19aeba Merge pull request #1431 from lightpanda-io/crash_handler_discord
add discord link to crash handler
2026-01-30 06:54:34 +08:00