[defer-import-eval] dynamic import with deferred evaluation support [v8/v8 : main]

2 views
Skip to first unread message

Caio Lima (Gerrit)

unread,
Jan 16, 2026, 2:48:25 PMJan 16
to Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com

Caio Lima added 3 comments

Patchset-level comments
File-level comment, Patchset 1 (Latest):
Caio Lima . resolved

This still is a WIP, but I'm submitting the patch so our conversation about how to implement `PerformPromiseAll` on C++ is more concrete.

File src/builtins/promise-all.tq
Line 395, Patchset 1 (Latest):transitioning macro PerformPromiseAllFixedArray(
Caio Lima . unresolved

This is not being used by current Patch, but it's here as a reference so we can compare the C++ version. It's mostly a copy and paste from `PerformPromiseAll` above, module the machinery to deal with iterator, instead of a FixedArray.

File src/objects/objects.cc
Line 4932, Patchset 1 (Latest):MaybeHandle<JSPromise> JSPromise::PerformPromiseAll(
Caio Lima . unresolved

This is the version of builtin function in C++, instead of torque. it might have some machinery missing or wrong, but it's a working version now.

Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: v8/v8
Gerrit-Branch: main
Gerrit-Change-Id: I25c246e74d04234dfbdbb1d06c64ce587f73b0bc
Gerrit-Change-Number: 7488270
Gerrit-PatchSet: 1
Gerrit-Owner: Caio Lima <caio...@igalia.com>
Gerrit-CC: Hannes Payer <hpa...@chromium.org>
Gerrit-Comment-Date: Fri, 16 Jan 2026 19:48:22 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Caio Lima (Gerrit)

unread,
Jan 22, 2026, 1:36:47 PM (13 days ago) Jan 22
to Olivier Flückiger, Leszek Swirski, V8 LUCI CQ, Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com
Attention needed from Leszek Swirski and Olivier Flückiger

Caio Lima added 1 comment

File include/v8-script.h
Line 278, Patchset 3 (Latest): V8_WARN_UNUSED_RESULT MaybeLocal<Value> DeferredEvaluate(
Caio Lima . unresolved

I'm tinking in actually rename it to `EvaluateAsyncDependencies`. It is probably a much better name. WDYT?

Open in Gerrit

Related details

Attention is currently required from:
  • Leszek Swirski
  • Olivier Flückiger
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: v8/v8
Gerrit-Branch: main
Gerrit-Change-Id: I25c246e74d04234dfbdbb1d06c64ce587f73b0bc
Gerrit-Change-Number: 7488270
Gerrit-PatchSet: 3
Gerrit-Owner: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Leszek Swirski <les...@chromium.org>
Gerrit-Reviewer: Olivier Flückiger <ol...@chromium.org>
Gerrit-CC: Hannes Payer <hpa...@chromium.org>
Gerrit-Attention: Olivier Flückiger <ol...@chromium.org>
Gerrit-Attention: Leszek Swirski <les...@chromium.org>
Gerrit-Comment-Date: Thu, 22 Jan 2026 18:36:43 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Olivier Flückiger (Gerrit)

unread,
Feb 3, 2026, 8:41:13 AM (22 hours ago) Feb 3
to Caio Lima, Leszek Swirski, V8 LUCI CQ, Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com
Attention needed from Caio Lima and Leszek Swirski

Olivier Flückiger added 6 comments

File include/v8-script.h
Line 278, Patchset 3 (Latest): V8_WARN_UNUSED_RESULT MaybeLocal<Value> DeferredEvaluate(
Caio Lima . unresolved

I'm tinking in actually rename it to `EvaluateAsyncDependencies`. It is probably a much better name. WDYT?

Olivier Flückiger

Or `EvaluateForImportDefer`?

Line 276, Patchset 3 (Latest): * dependencies are not going to be evaluated.
Olivier Flückiger . unresolved

Implements 13.3.10.4.1 ContinueDynamicImport, Step 6.e.

File src/api/api.cc
Line 2425, Patchset 3 (Latest): has_error = true;
Olivier Flückiger . unresolved

nit: return here, instead of break.

Line 2429, Patchset 3 (Latest): CHECK(eval_result->IsPromise());
Olivier Flückiger . unresolved

SyntheticModules don't seem to return promises. Am I missing something?

File src/objects/js-promise.h
Line 72, Patchset 3 (Latest): static MaybeHandle<JSPromise> PerformPromiseAll(
Olivier Flückiger . unresolved

Let's add a comment that this is limited to the case

`PerformPromiseAll([native-promise, ...], %Promise%, NewPromiseCapability(%Promise%), %Promise.resolve%)`

File src/objects/objects.cc
Line 4932, Patchset 1:MaybeHandle<JSPromise> JSPromise::PerformPromiseAll(
Caio Lima . unresolved

This is the version of builtin function in C++, instead of torque. it might have some machinery missing or wrong, but it's a working version now.

Olivier Flückiger

I had good success recently letting gemini help with translations from torque to C++. Here is what it had to say:

✦ Under the assumption that we are using the native %Promise% constructor, native %Promise.resolve%, and a list of native Promises (the "Fast Path"), the C++ implementation is largely behaviorally equivalent to the Torque implementation. It correctly avoids allocating throwaway promises (by passing undefined to PerformPromiseThen) and correctly suppresses debug events for the internal capability.

However, there are two remaining observable discrepancies:


1. Missing Debugger Support (Catch Prediction)
The Torque implementation explicitly marks the reject handler of the capability as a "forwarding" handler when the debugger is active. This allows the V8 debugger to correctly predict that a rejection flowing through Promise.all will be caught later, preventing false positive "Uncaught Exception" pauses.


* Torque (`src/builtins/promise-all.tq`):

1 // For catch prediction, don't treat the .then calls as handling it;
2 // instead, recurse outwards.
3 if (IsDebugActive()) deferred {
4 SetPropertyStrict(context, reject, kPromiseForwardingHandlerSymbol, True);
5 }
* C++ (`src/objects/objects.cc`):
This check and property assignment are completely missing.
                                                                                                                        
Consequence: When debugging, rejections occurring within the Promise.all chain might be incorrectly flagged as "uncaught" by the debugger, even if the result of Promise.all has a .catch() attached.


2. Missing Range Check (Too Many Elements)
The Torque implementation enforces a hard limit on the number of elements, corresponding to the maximum size of the hash field where the index is stored (kPropertyArrayHashFieldMax, approximately 2 million).

* Torque (`src/builtins/promise-all.tq`):
   1     // Check if we reached the limit.        
2 if (index == kPropertyArrayHashFieldMax) {
3 ThrowRangeError(MessageTemplate::kTooManyElementsInPromiseCombinator, 'all');
4 }
* C++ (`src/objects/objects.cc`):
The C++ implementation iterates over the std::vector and casts the size to int. It does not check against kPropertyArrayHashFieldMax. It passes the raw index to factory->CreatePromiseAllResolveElementFunction.
  Consequence: If asyncDepsEvaluationPromises contains more than ~2.1 million elements ($2^{21}$), the Torque version correctly throws a RangeError. The C++ version will proceed, likely corrupting the properties_or_hash field of the created resolve functions (due to bitfield overflow), leading to undefined behavior or a crash when those functions are eventually executed.
Open in Gerrit

Related details

Attention is currently required from:
  • Caio Lima
  • Leszek Swirski
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: v8/v8
Gerrit-Branch: main
Gerrit-Change-Id: I25c246e74d04234dfbdbb1d06c64ce587f73b0bc
Gerrit-Change-Number: 7488270
Gerrit-PatchSet: 3
Gerrit-Owner: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Leszek Swirski <les...@chromium.org>
Gerrit-Reviewer: Olivier Flückiger <ol...@chromium.org>
Gerrit-CC: Hannes Payer <hpa...@chromium.org>
Gerrit-Attention: Caio Lima <caio...@igalia.com>
Gerrit-Attention: Leszek Swirski <les...@chromium.org>
Gerrit-Comment-Date: Tue, 03 Feb 2026 13:41:07 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Caio Lima <caio...@igalia.com>
unsatisfied_requirement
open
diffy

Olivier Flückiger (Gerrit)

unread,
Feb 3, 2026, 8:47:54 AM (21 hours ago) Feb 3
to Caio Lima, Leszek Swirski, V8 LUCI CQ, Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com
Attention needed from Caio Lima and Leszek Swirski

Olivier Flückiger added 2 comments

File src/objects/objects.cc
Line 4973, Patchset 3 (Latest): resolve_element_context->SetNoCell(
Olivier Flückiger . unresolved

is this intermediate count observable somehow or could we just set it to "length" outside the loop and be done with it?

Line 5005, Patchset 3 (Latest): if (final_remaining == 0) {
Olivier Flückiger . unresolved

I think this cannot happen due to line 4949

Gerrit-Comment-Date: Tue, 03 Feb 2026 13:47:49 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Caio Lima (Gerrit)

unread,
Feb 3, 2026, 9:45:47 AM (21 hours ago) Feb 3
to Olivier Flückiger, Leszek Swirski, V8 LUCI CQ, Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com
Attention needed from Leszek Swirski and Olivier Flückiger

Caio Lima added 5 comments

Patchset-level comments
File-level comment, Patchset 3 (Latest):
Caio Lima . resolved

Thank you very much for the review! I'll fix them ASAP.

File src/api/api.cc
Line 2429, Patchset 3 (Latest): CHECK(eval_result->IsPromise());
Olivier Flückiger . unresolved

SyntheticModules don't seem to return promises. Am I missing something?

Caio Lima

We can't have `SyntheticModules`, because they are always evaluated synchronously. Here we just evaluate asynchronous dependencies (i.e SourceTextModules with TLA).

File src/objects/objects.cc
Caio Lima

Regarding debugging checks, I'm not 100% confident, but I've tested the following on Chrome and I couldn't reach the "Pause on uncaught exception", just when I enable "Pause on caught exception":

```
// a.mjs
throw new Error();
await 0;

// b.mjs
await 42;

// entrypoint.mjs
let a = import("a.mjs");
let b - import("b.mjs");

let [a_ns, b_ns] = Promise.all([a, b]);
```

When I enable "Pause on caught exception", the execution then breaks at `a.mjs:1` `throw`.

My test removed the debugging setup from `promise-all.tq`, and I've found no difference on debugger behavior. Given that, I decided to not include the debugging machinery here. IIUC, exceptions thrown while a module is being evaluated is considered a caught by its Promising wrapping.

Line 4973, Patchset 3 (Latest): resolve_element_context->SetNoCell(
Olivier Flückiger . unresolved

is this intermediate count observable somehow or could we just set it to "length" outside the loop and be done with it?

Caio Lima

I'll double check it. It came mostly from original torque file, but I was thinking in the condition where `perform_promise_then` is called with an already fulfilled promise. But thinking this through, I think the resolve callback for each Promise is only going to run on next micro task and this logic is here to handle user-defined Promises.

Line 5005, Patchset 3 (Latest): if (final_remaining == 0) {
Olivier Flückiger . unresolved

I think this cannot happen due to line 4949

Caio Lima

The logic is the same I mentioned above. Probably it's here because of user-defined promises, but this implementation only considers builtin promises. If I confirm that, I'll remove this part.

Open in Gerrit

Related details

Attention is currently required from:
  • Leszek Swirski
  • Olivier Flückiger
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: v8/v8
Gerrit-Branch: main
Gerrit-Change-Id: I25c246e74d04234dfbdbb1d06c64ce587f73b0bc
Gerrit-Change-Number: 7488270
Gerrit-PatchSet: 3
Gerrit-Owner: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Leszek Swirski <les...@chromium.org>
Gerrit-Reviewer: Olivier Flückiger <ol...@chromium.org>
Gerrit-CC: Hannes Payer <hpa...@chromium.org>
Gerrit-Attention: Olivier Flückiger <ol...@chromium.org>
Gerrit-Attention: Leszek Swirski <les...@chromium.org>
Gerrit-Comment-Date: Tue, 03 Feb 2026 14:45:41 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Caio Lima <caio...@igalia.com>
Comment-In-Reply-To: Olivier Flückiger <ol...@chromium.org>
unsatisfied_requirement
open
diffy

Olivier Flückiger (Gerrit)

unread,
Feb 3, 2026, 10:45:43 AM (20 hours ago) Feb 3
to Caio Lima, Leszek Swirski, V8 LUCI CQ, Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com
Attention needed from Caio Lima and Leszek Swirski

Olivier Flückiger added 2 comments

File src/api/api.cc
Line 2429, Patchset 3 (Latest): CHECK(eval_result->IsPromise());
Olivier Flückiger . unresolved

SyntheticModules don't seem to return promises. Am I missing something?

Caio Lima

We can't have `SyntheticModules`, because they are always evaluated synchronously. Here we just evaluate asynchronous dependencies (i.e SourceTextModules with TLA).

Olivier Flückiger

Ah right. Could we maybe type the evaluation_list in GatherAsynchronousTransitiveDependencies a list of SourceTextModule's then?

File src/objects/objects.cc
Olivier Flückiger

I see. Tbh. I am not familiar with the debugger integration.

What I would like to avoid is that the PerformPromiseAll misbehaves when used in a different context.

So, I am totally fine with it having limitations on how you can use it. But I would like that we understand (and check or restrict by construction) what the limitations are.

With the debugger I am not sure. If I understand the comment correctly the difference might become observable if you add a try/catch block around Promise.all?

Open in Gerrit

Related details

Attention is currently required from:
  • Caio Lima
  • Leszek Swirski
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: v8/v8
Gerrit-Branch: main
Gerrit-Change-Id: I25c246e74d04234dfbdbb1d06c64ce587f73b0bc
Gerrit-Change-Number: 7488270
Gerrit-PatchSet: 3
Gerrit-Owner: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Leszek Swirski <les...@chromium.org>
Gerrit-Reviewer: Olivier Flückiger <ol...@chromium.org>
Gerrit-CC: Hannes Payer <hpa...@chromium.org>
Gerrit-Attention: Caio Lima <caio...@igalia.com>
Gerrit-Attention: Leszek Swirski <les...@chromium.org>
Gerrit-Comment-Date: Tue, 03 Feb 2026 15:45:37 +0000
unsatisfied_requirement
open
diffy

Caio Lima (Gerrit)

unread,
Feb 3, 2026, 12:04:13 PM (18 hours ago) Feb 3
to Olivier Flückiger, Leszek Swirski, V8 LUCI CQ, Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com
Attention needed from Leszek Swirski and Olivier Flückiger

Caio Lima added 2 comments

File src/api/api.cc
Line 2429, Patchset 3 (Latest): CHECK(eval_result->IsPromise());
Olivier Flückiger . unresolved

SyntheticModules don't seem to return promises. Am I missing something?

Caio Lima

We can't have `SyntheticModules`, because they are always evaluated synchronously. Here we just evaluate asynchronous dependencies (i.e SourceTextModules with TLA).

Olivier Flückiger

Ah right. Could we maybe type the evaluation_list in GatherAsynchronousTransitiveDependencies a list of SourceTextModule's then?

Caio Lima

Makes sense!

File src/objects/objects.cc
Caio Lima

If there's a try catch capturing `Promise.all`, and we enable "Pause on caught exception", the behavior is the same as well, because it will pause when `throw` in `a.mjs` happens. I don't fully understand this interaction with the debugger, but I'll get a deeper understanding to properly set the implementation.

Open in Gerrit

Related details

Attention is currently required from:
  • Leszek Swirski
  • Olivier Flückiger
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: v8/v8
Gerrit-Branch: main
Gerrit-Change-Id: I25c246e74d04234dfbdbb1d06c64ce587f73b0bc
Gerrit-Change-Number: 7488270
Gerrit-PatchSet: 3
Gerrit-Owner: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Leszek Swirski <les...@chromium.org>
Gerrit-Reviewer: Olivier Flückiger <ol...@chromium.org>
Gerrit-CC: Hannes Payer <hpa...@chromium.org>
Gerrit-Attention: Olivier Flückiger <ol...@chromium.org>
Gerrit-Attention: Leszek Swirski <les...@chromium.org>
Gerrit-Comment-Date: Tue, 03 Feb 2026 17:04:07 +0000
unsatisfied_requirement
open
diffy

Olivier Flückiger (Gerrit)

unread,
Feb 3, 2026, 12:28:48 PM (18 hours ago) Feb 3
to Caio Lima, Leszek Swirski, V8 LUCI CQ, Hannes Payer, cbruni...@chromium.org, mlippau...@chromium.org, v8-re...@googlegroups.com
Attention needed from Caio Lima and Leszek Swirski

Olivier Flückiger added 1 comment

File src/objects/objects.cc
Attention is currently required from:
  • Caio Lima
  • Leszek Swirski
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: v8/v8
Gerrit-Branch: main
Gerrit-Change-Id: I25c246e74d04234dfbdbb1d06c64ce587f73b0bc
Gerrit-Change-Number: 7488270
Gerrit-PatchSet: 3
Gerrit-Owner: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Caio Lima <caio...@igalia.com>
Gerrit-Reviewer: Leszek Swirski <les...@chromium.org>
Gerrit-Reviewer: Olivier Flückiger <ol...@chromium.org>
Gerrit-CC: Hannes Payer <hpa...@chromium.org>
Gerrit-Attention: Caio Lima <caio...@igalia.com>
Gerrit-Attention: Leszek Swirski <les...@chromium.org>
Gerrit-Comment-Date: Tue, 03 Feb 2026 17:28:43 +0000
unsatisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages